10

MSVC9.0でコンパイルされた次のコードは、Destructorを4回実行して出力します。これは、論理的です。

#include <iostream>
class SomeClass
{
public:
   void CommitSuicide()
   {
      delete this;
   }
   void Reincarnate()
   {
      this->~SomeClass();
      new (this) SomeClass;
   }
   ~SomeClass()
   {
      std::cout  << "Destructor\n";
   }
};

int main()
{
   SomeClass* p = new SomeClass;
   p->CommitSuicide();
   p =  new SomeClass;
   p->Reincarnate();
   p->~SomeClass(); //line 5
   p->CommitSuicide();
}

mainの最初の4行のコードは、未定義の動作を引き起こさないと思います(ただし、完全にはわかりませんdelete this;)。その確認または<確認の反意語のプレースホルダー>が欲しいのですが。しかし、5行目と6行目については深刻な疑問があります。デストラクタを明示的に呼び出すことは許可されていますね。しかし、オブジェクトの存続期間はその後終了したと見なされますか?つまり、デストラクタの明示的な呼び出し後の別のメンバーの呼び出しは許可されていますか(定義されています)?

要約すると、上記のコードのどの部分(存在する場合)が未定義の動作(技術的に言えば)をもたらしますか?

4

3 に答える 3

7

delete this;大丈夫です。最後p->CommitSuicide();は、「5行目」でオブジェクトを既に破棄しているため、未定義の動作を示します。

于 2010-10-18T13:43:45.740 に答える
2

p->〜SomeClass(); //5行目

p-> CommitSuicide(); //6行目

行(6)は、間違いなく未定義動作を呼び出します。

つまり、デストラクタの明示的な呼び出し後の別のメンバーの呼び出しは許可されていますか(定義されています)?

いいえ!あなたの仮定は正しいです。

于 2010-10-18T13:43:09.963 に答える
0

「これを削除」は、削除後にそのオブジェクトのコードを呼び出さない限り(デストラクタでさえも)問題ありません。したがって、自己削除オブジェクトはヒープにのみ配置され、スタックでの作成から保護するためのプライベートデストラクタが必要です。

デストラクタを直接呼び出すと未定義の動作が発生するかどうかはわかりませんが、ユーザー定義の削除演算子は実行されません。

于 2010-10-18T13:43:59.733 に答える