10

下面用MSVC9.0编译的代码运行四次,输出Destructor ,符合逻辑。

#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 回答