47411


純枠仮想デスストラクタの「ここです」とコメントしてある部分なのですが純枠仮想デスストラクタにする意味を教えてほしいです、普通のデスストラクタにして実行してみましたがこの場合は効果が同じなので利点を理解できません。  
１．利点を教えてほしいです  
２、純枠仮想関数に定義を書くと挙動がどう変わるのか知りたいです。  
３、参考書に、「あるメンバ関数から、そのクラス内で本体が定義されてない純粋仮想関数を呼び出す式がコンパイルエラーとなることはない」とありますが。どのようなことなのか教えてほしいです。

[code]

    　　　　    #include <iostream>
            #include "conio.h"
            #include <string>
            //using namespace std;
    
    
            class Animal {
            private:
                std::string name;
            public:
    
                virtual ~Animal() = 0;//コードを編集しました。
                Animal(const std::string& n) : name(n) { }
    
                virtual void bark() = 0;
    
                virtual std::string to_string() = 0;
    
                std::string get_name() {
                    return name;
                }
    
                void introduce() {
                    std::cout << to_string() + "だ";
                    bark();
                    std::cout << "\n";
                }
    
            };
    
            inline Animal::~Animal() { }//ここです。
    
            class Dog : public Animal {
            private:
                std::string type;
            public:
                Dog(const std::string& n, const std::string& t) : Animal(n), type(t) {  }
    
                virtual void bark() { std::cout<< "ワンワン!!"; }
    
                virtual std::string to_string() {
                    return type + "の" + get_name();
                }
    
            };
    
            class Cat : public Animal {
            private:
                std::string fav;
            public:
    
                Cat(const std::string& n, const std::string& f) : Animal(n),fav(f){ }
    
                virtual void bark() {
                    std::cout << "にゃーん";
                }
    
                virtual std::string to_string() {
                    return fav + "が好きな" + get_name();
                }
    
    
            };
    
    
            int main() {
    
                int i = 0;
                Animal *p[] = {
                    new Dog("dog_A","D_a"),
                    new Cat("Cat_a","C_a"),
                    new Dog("dog_B","D_b"),
                };
    
                for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
                    p[i]->introduce();
                }
    
                i = 0;
                for (i; i < sizeof(p) / sizeof(p[0]); i++) {
                    delete p[i];
                }
    
    
    
                _getch();
                return 0;
            }
    
[/code]


CC BY-SA 4.0
2018-08-10T07:35:21.843
47410
2018-08-11T01:28:41.863
2018-08-11T01:28:41.863
question
c++
c++の純粋仮想について知りたいことがあります。


まず最初にデスストラクタではありません。綴りは`destructor`であり、カタカナ表記するのであれば`デストラクタ`です。  
次に純枠仮想デストラクタではありません。`virtual`のことは日本語では`仮想`と記述します。

[code]

    virtual void bark() = 0;
    
[/code]

のように`= 0`を付けた上で、関数実体を定義しないもののことを`pure virtual
function`、`純枠仮想関数`と呼びます（関数実体を定義してもかまいませんが…）。  
今回、デストラクタには`= 0`が付けられていないので純枠仮想デストラクタではなく、単なる`仮想デストラクタ`です。

* * *

## 仮想デストラクタの利点

[code]

    Animal* p = new Dog("dog_A","D_a"),
    delete p;
    
[/code]

というコードで変数`p`のコンパイル時型は`Animal`なのに対し実行時型は`Dog`です。

`Animal`クラスが通常のデストラクタの場合、`delete
p`行ではコンパイル時に分かっている`Animal`デストラクタしか実行されないため、`Dog`クラスに対して解放処理が行われずリソースリークします。  
`Anminal`クラスが仮想デストラクタの場合、`delete
p`行では実行時にデストラクタの検索が行われて`Dog`デストラクタが実行され正しく解放処理が行われます。


CC BY-SA 4.0
2018-08-10T08:28:50.787
47411
2018-08-10T08:28:50.787
4236
47410
answer