以下使用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行有严重怀疑。允许显式调用析构函数,不是吗?但在此之后,对象的生命周期是否已经完成?也就是说,在析构函数的显式调用允许(定义)后调用另一个成员?
总结一下,上面代码的哪些部分(如果有的话)导致了未定义的行为(从技术上讲)?
答案 0 :(得分:6)
delete this;
没问题。最后一个p->CommitSuicide();
给出了未定义的行为,因为您已经在“第5行”中销毁了该对象。
答案 1 :(得分:2)
对 - &GT;〜SomeClass的(); //第5行
对 - &GT; CommitSuicide(); //第6行
Line(6)肯定会调用未定义的行为。
也就是说,在显式调用析构函数后允许(定义)调用另一个成员?
没有!你的假设是正确的。
答案 2 :(得分:0)
“删除此”是可以的,只要您在删除后不尝试调用该对象的任何代码(甚至不是析构函数)。所以一个自我删除的对象只能放在堆上,并且有一个私有的析构函数来防止在堆栈上创建。
我不知道对析构函数的直接调用是否会导致未定义的行为,但是用户定义的delete-operator不会被执行。