仮想デストラクタ
デストラクタ:インデックス への移動
デストラクタを仮想として宣言することができます。これにより,基本クラスオブジェクトを指すポインタが実際には派生クラスオブジェクトを参照している場合に,そのポインタが正しいデストラクタを呼び出すことが可能になります。仮想デストラクタを持つクラスから派生するクラスのデストラクタは,それ自体が仮想になります。
/* デストラクタの呼び出し順序に与える仮想の影響
基本クラスに仮想デストラクタがない場合,
派生クラスのデストラクタは呼び出されない */
#include <iostream>
class color {
public:
virtual ~color() { // color の仮想デストラクタ
std::cout << "color dtor\n";
}
};
class red : public color {
public:
~red() { // red のデストラクタも仮想
std::cout << "red dtor\n";
}
};
class brightred : public red {
public:
~brightred() { // brightred のデストラクタも仮想
std::cout << "brightred dtor\n";
}
};
int main()
{
color *palette[3];
palette[0] = new red;
palette[1] = new brightred;
palette[2] = new color;
// red と color のデストラクタが呼び出される
delete palette[0];
std::cout << std::endl;
// bright red,red,および color のデストラクタが呼び出される
delete palette[1];
std::cout << std::endl;
// color のデストラクタが呼び出される
delete palette[2];
return 0;
}
プログラムの出力:
red dtor
color dtor
brightred dtor
red dtor
color dtor
color dtor
ただし,仮想として宣言されたデストラクタがない場合は,delete palette[0],delete palette[1],delete palette[2] は,どれもクラス color のデストラクタのみを呼び出します。これにより,最初の 2 つの要素は実際には red 型と brightred 型であるにもかかわらず,誤って破壊されることがあります。