親クラスのデストラクタには必ずvirtualが必要な理由

virtualをつけないと、親クラスのポインタに子クラスを格納しているケースにおいて、親クラスのポインタをdeleteしても親クラスのデストラクタしか呼ばれないため。

// デストラクタにvirtualがついているケース
using namespace std;

class Parent{
public:    
    virtual ~Parent(){
        cout << "Parent::~Parent()" << endl;
    }
};

class Child final: public Parent{
public:
    ~Child() override{
        cout << "Child::~Child()" << endl;
    }
};

int main()
{
    Parent* oya = new Child();
    delete oya;
    return 0;
}

// 実行結果
Child::~Child()
Parent::~Parent()
// デストラクタにvirtualがついていないケース
using namespace std;

class Parent{
public:    
    ~Parent(){
        cout << "Parent::~Parent()" << endl;
    }
};

class Child final: public Parent{
public:
    ~Child(){
        cout << "Child::~Child()" << endl;
    }
};

int main()
{
    Parent* oya = new Child();
    delete oya;
    return 0;
}

// 実行結果
Parent::~Parent()

こういったミスを犯さないポイントとして、子クラスのデストラクタ定義時に、overrideを付与する癖をつけておけば、親のデストラクタにvirtualがついていなければコンパイルエラーになるので気づきやすい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です