ここで「単純」とは、非仮想の空のデストラクタまたは POD 型を持つクラスを意味します。
典型的な例:
char buffer[SIZE];
T *p = new(buffer) T;
...
p->~T(); // <---- always ?
で明示的なデストラクタを呼び出さないとどうなりp
ますか? 未定義の動作やメモリリークではないと思います。
再利用しても問題ありませbuffer
んか?
ここで「単純」とは、非仮想の空のデストラクタまたは POD 型を持つクラスを意味します。
典型的な例:
char buffer[SIZE];
T *p = new(buffer) T;
...
p->~T(); // <---- always ?
で明示的なデストラクタを呼び出さないとどうなりp
ますか? 未定義の動作やメモリリークではないと思います。
再利用しても問題ありませbuffer
んか?
技術的に言えば、デストラクタが建設中に取得したリソースを解放しないと仮定すると、それは必要ないかもしれません。
ただし、非技術的な側面(コードの保守と進化)を考慮すると、ベストプラクティスに固執します。構築されたものは、破棄する必要があります。考慮すべきシナリオ-将来、いくつかの変更により、デストラクタに配置する関連コードが決定される場合はどうなりますか?そのタイプのオブジェクトの破壊を避けたことを覚えていますか?
POD 型または単純なデストラクタを持つクラスの場合:いいえ。オブジェクトのストレージが解放または再利用されると、オブジェクトの存続期間は終了します。したくない場合は、デストラクタを明示的に呼び出す必要はありません。
そうは言っても、そうしない理由はありません。自明なデストラクタを持つ型の場合、デストラクタ呼び出しはコードを生成しません。
「空の」デストラクタを持つクラスによって、クラスに自明でないデストラクタを持つメンバーまたは基本クラスがある可能性を許容している場合、プログラムがこれらのデストラクタの呼び出しに依存している場合、未定義の動作が発生する可能性があります。
ユーザー提供のデストラクタは、非仮想で空であっても、非自明なデストラクタであることに注意してください。それにもかかわらず、プログラムがデストラクタの副作用に依存していなければ、ストレージを解放または再利用するだけで、そのようなデストラクタを使用してオブジェクトの存続期間を終了することができます。(ISO/IEC 14882:2011 の 3.8 [basic.life] / 4 を参照)
クラスがいくつかのリソース (ヒープ メモリ、ハンドル、カウンター、ミューテックスなど) を処理するか、リソースを処理するいくつかのフィールドを含む場合、デストラクタを明示的に呼び出さないと、このリソースは解放されません。それ以外の場合は、破壊に問題はありません。破壊されていないクラスをメモリ内のガベージと見なし、同じ場所に自由に新しいクラスを構築できます。
はい、明示的にデストラクタを呼び出す必要があります (T の副作用、つまり追加のメモリを解放することに注意してください)。また、placement new を使用する場合は、メモリ アラインメントに注意する必要があります。
必要に応じて、バッファ メモリを再利用できます。
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14も参照してください。