1. ホーム
  2. c++

[解決済み] 仮想デストラクタはいつ使うのか?

2022-03-15 15:38:32

質問

ほとんどのことをしっかり理解しています OOP の理論がありますが、その中でも特に混乱するのが仮想デストラクタです。

デストラクタは、何があっても、チェーン内のすべてのオブジェクトに対して常に呼び出されると思っていました。

仮想化するタイミングとその理由を教えてください。

どのように解決するのですか?

仮想デストラクタは、ベースクラスへのポインタを介して派生クラスのインスタンスを削除する可能性がある場合に便利です。

class Base 
{
    // some virtual methods
};

class Derived : public Base
{
    ~Derived()
    {
        // Do some important cleanup
    }
};

ここで、Baseのデストラクタを宣言していないことに気がつくだろう。 virtual . では、次のスニペットを見てみましょう。

Base *b = new Derived();
// use b
delete b; // Here's the problem!

Baseのデストラクタは virtualbBase* を指している。 Derived オブジェクトを作成します。 delete b があります。 未定義の動作 :

[イン delete b ]の場合、その静的型が 削除されるオブジェクトがその動的な型と異なる場合、静的な 型は,対象となるオブジェクトの動的型の基底クラスでなければならない。 削除され 静的型が仮想デストラクタを持つか、または 動作は未定義 .

つまり、ベースクラスのデストラクタは呼び出されるのに、派生クラスのデストラクタは呼び出されないので、リソースリークが発生します。

結論として、ベースクラスのデストラクタは常に virtual は、ポリモーフィックに操作されることを意図している場合です。

もしベースクラスのポインタからインスタンスが削除されるのを防ぎたければ、ベースクラスのデストラクタをprotectedかつnon-virtualにすればよい。 delete をベースクラスポインタの上に置くことができます。

仮想性と仮想基底クラスのデストラクタについては、以下のページで詳しく説明しています。 Herb Sutterの記事 .