いつ/なぜ仮想デストラクタを使用する必要がありますか?
ハーブサッターのガイドラインに従ってください:
基本クラスのデストラクタは、パブリックと仮想、または保護された非仮想のいずれかである必要があります
これは未定義動作として分類できますか(〜D()が確実に呼び出されることはないことを認識しています)?
これは標準による未定義動作であり、通常、派生クラスのデストラクタが呼び出されず、メモリリークが発生しますが、標準はこの点に関して何も保証しないため、未定義動作の影響後を推測することは関係ありません。 。
C ++ 03標準:5.3.5削除
5.3.5 / 1:
式の削除演算子は、new-expressionによって作成された最も派生したオブジェクト(1.8)または配列を破棄します。
削除式
:::opt削除キャスト式
::opt削除[]キャスト式
5.3.5 / 3:
最初の選択肢(オブジェクトの削除)では、オペランドの静的型が動的型と異なる場合、静的型はオペランドの動的型の基本クラスであり、静的型は仮想デストラクタを持っているか、動作が未定義です。 。2番目の選択肢(配列の削除)では、削除するオブジェクトの動的タイプが静的タイプと異なる場合、動作は未定義です73)。
~D()
空の場合はどうなりますか。それはコードに何らかの影響を及ぼしますか?
それでも、標準では未定義動作です。派生クラスのデストラクタが空の場合、プログラムは正常に動作する可能性がありますが、これも特定の実装の実装定義の側面であり、技術的には未定義動作です。
ここでは、派生クラスのデストラクタを仮想化しないと、派生クラスのデストラクタが呼び出されないという保証はなく、この仮定は正しくないことに注意してください。標準に従って、未定義動作の土地でクロスオーバーすると、すべての賭けはオフになります。
彼の標準が未定義動作について言っていることに注意してください。
C ++ 03標準:1.3.12未定義動作[defns.undefined]
この国際規格が要件を課していない、誤ったプログラム構成または誤ったデータの使用時に発生する可能性があるような動作。この国際規格が動作の明示的な定義の説明を省略している場合も、未定義の動作が予想される場合があります。[注:許容される未定義の動作は、予測できない結果で状況を完全に無視することから、翻訳またはプログラムの実行中に環境に特徴的な文書化された方法で動作すること(診断メッセージの発行の有無にかかわらず)、翻訳または実行の終了にまで及びます(診断メッセージの発行を伴う)。多くの誤ったプログラム構成は、未定義の動作を引き起こしません。それらは診断される必要があります。]
派生したデストラクタのみが呼び出されない場合は、上記の引用の太字のテキストが適用されます。これは、実装ごとに明らかに開いたままになっています。