面向对象的自杀或删除此;

时间:2010-10-18 13:29:06

标签: c++ destructor delete-operator self-destruction

以下使用MSVC9.0编译的代码运行并输出析构函数四次,这是合乎逻辑的。

#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;的事情)。我想要一个确认或&lt;占位符用于确认的反义词&gt; 。但我对第5行和第6行有严重怀疑。允许显式调用析构函数,不是吗?但在此之后,对象的生命周期是否已经完成?也就是说,在析构函数的显式调用允许(定义)后调用另一个成员?

总结一下,上面代码的哪些部分(如果有的话)导致了未定义的行为(从技术上讲)?

3 个答案:

答案 0 :(得分:6)

delete this;没问题。最后一个p->CommitSuicide();给出了未定义的行为,因为您已经在“第5行”中销毁了该对象。

答案 1 :(得分:2)

  

对 - &GT;〜SomeClass的(); //第5行

     

对 - &GT; CommitSuicide(); //第6行

Line(6)肯定会调用未定义的行为。

  

也就是说,在显式调用析构函数后允许(定义)调用另一个成员?

没有!你的假设是正确的。

答案 2 :(得分:0)

“删除此”是可以的,只要您在删除后不尝试调用该对象的任何代码(甚至不是析构函数)。所以一个自我删除的对象只能放在堆上,并且有一个私有的析构函数来防止在堆栈上创建。

我不知道对析构函数的直接调用是否会导致未定义的行为,但是用户定义的delete-operator不会被执行。