仮想デストラクタとは、基底クラスでvirtualキーワードを使用して宣言されたデストラクタです。これにより、基底クラスへのポインタを介してオブジェクトを削除する際に派生クラスのデストラクタが呼び出されることが保証されます。
class Base { public: virtual ~Base() { /* ... */ } }; class Derived : public Base { public: ~Derived() override { /* ... */ } }; Base* ptr = new Derived(); delete ptr; // 両方のデストラクタが呼び出されます。
仮想デストラクタがない場合、不正な動作が発生する可能性があります — 派生クラスのデストラクタが呼び出されず、リソースリークが発生します!
基底クラスに仮想関数が一つもない場合、デストラクタを仮想として宣言する必要がありますか?
回答:はい、基底型ポインタを介して削除されることが想定される場合、クラスから派生する場合は必要です。 他に仮想関数がなくても、派生クラスを正しく削除するためにデストラクタの仮想性は必要です。
class Shape { public: virtual ~Shape() {} };
ストーリー1
大規模なグラフィックライブラリプロジェクトで、基底クラスへのポインタを介してオブジェクトを削除する際にOpenGLリソース(バッファ、テクスチャ)がリークしていました — 派生クラスのデストラクタで対応する解放が行われていましたが、それが呼び出されませんでした。
ストーリー2
TCPプロトコルのネットワークライブラリで、セッションを削除する際に、基底インターフェースを介して管理される派生クラスのデストラクタが呼び出されませんでした。これにより、ソケットが大規模にハングし、ディスクリプタの制限が枯渇しました。
ストーリー3
C++での埋め込みシステムで、基底クラスのデストラクタが正しく宣言(非virtual)されていなかったため、入出力コントローラのシステムリソースにメモリリークが発生し、デバイスが数回のドライバ更新サイクル後に故障しました。