0

最近のインタビューで、このコードが安全かどうか、また安全である場合、次のようなものをいつ使用するかを尋ねられました。

template<class T> T *CTricky<T>::Safe_Or_Not (T *object) 
{ 

    object->T::~T (); 

    ::new (object) T; 

    return object; 

 }

私の答えは次のとおりです。このコードは安全であり、デストラクタを呼び出して「オブジェクト」で使用されているリソースを解放する必要がある場合は、この手法を使用しますが、同時に「オブジェクト」の割り当てを解除したくありませんでした。メモリ内の場所を保持します(ここで新しい配置によって達成されます)。

正直なところ、面接でこの質問に正しく答える助けを求めているわけではありません。新規および明示的なデストラクタ呼び出しの配置に関する私の理解が正しいかどうかを知りたいだけです。

4

3 に答える 3

2

短い答え: 必ずしも問題が発生するわけではありませんが、これを本当に安全に行うのは非常に困難です。最大の問題は、プレースメント new スローを介して呼び出されたコンストラクターがオブジェクトを既に破棄している場合、スタックの巻き戻しによってオブジェクトが再度破棄され、未定義の動作が発生することです。

他にも注意すべき点がいくつかありますが (null ポインターなど)、これはおそらく最も目立たず、問題を引き起こさないようにするのが最も難しいものです (基本的に、唯一の選択肢は、未定義の動作に我慢することと、最善を期待するか、スタックの巻き戻しが発生する前に例外をキャッチしてプログラムを終了します)。

于 2014-02-12T06:30:28.973 に答える
1

安全ではありません: 以下はメモリリークを引き起こす可能性があります: ( https://ideone.com/70YqhM )

Base* b = new Derived;
b = Safe_Or_Not(b);

派生デストラクタは呼び出されません。

そして他の言及として:

  • ヌルチェックなし。
  • 例外安全性は考慮されていません
于 2014-02-12T10:10:24.153 に答える