親クラスのデストラクタが仮想ではなく、サブクラスに追加メンバーがない場合、親クラスのデストラクタを使用しても安全ですか?
class A{
~A();
protected:
int i;
};
class B: public A{
}
A *x = new B; delete x;
親クラスのデストラクタが仮想ではなく、サブクラスに追加メンバーがない場合、親クラスのデストラクタを使用しても安全ですか?
class A{
~A();
protected:
int i;
};
class B: public A{
}
A *x = new B; delete x;
短い答えはノーです。安全ではありません。
安全ではありません。§5.3.5 による未定義の動作です。
5.3.5 削除 [expr.delete]
3最初の選択肢 (オブジェクトの削除) では、削除されるオブジェクトの静的タイプがその動的タイプと異なる場合、静的タイプは削除されるオブジェクトの動的タイプの基本クラスであり、静的タイプは削除される必要があります。仮想デストラクタがあるか、動作が未定義です。2 番目の選択肢 (配列の削除) では、削除するオブジェクトの動的な型がその静的な型と異なる場合、動作は未定義です。
壊れる可能性がある理由の例は次のとおりです。
class A
{
public:
~A();
protected:
int i;
};
class B: public A
{
virtual void dummy();
}
A *x = new B; delete x;
vtblB
があるため、オブジェクトのレイアウトが異なります。
ところでpublic class A
、Java またはその他の言語ですが、C++ ではありません。
なぜリスクを取るのですか?
基本クラスも破棄されるようにするための数バイトは、それほど大きな打撃ではありません。
メモリリークも防ぎます。