Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 面向对象自杀或删除此项;_C++_Destructor_Delete Operator_Self Destruction - Fatal编程技术网

C++ 面向对象自杀或删除此项;

C++ 面向对象自杀或删除此项;,c++,destructor,delete-operator,self-destruction,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() {

以下使用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();
}
#包括
上课
{
公众:
无效杀螨剂()
{
删除此项;
}
虚空转世()
{
这个->~SomeClass();
新的(这个)某类;
}
~SomeClass()
{
std::cout commitsucide();
p=新类别;
p->转世();
p->~SomeClass();//第5行
p->commitsucide();
}

我认为主要的前4行代码不会导致未定义的行为(尽管不完全确定
删除这个;
东西).我想得到一个确认或。但是我对第5行和第6行有严重的怀疑。它可以显式调用析构函数,不是吗?但是对象的生存期是否被认为在这之后已经结束了?也就是说,在显式调用dest之后是否调用了另一个成员是否允许(已定义)或不允许

总而言之,上述代码的哪些部分(如果有)会导致未定义的行为(从技术上讲)

p->~SomeClass();//第5行

p->commitsucide();//第6行

第(6)行肯定调用了未定义的行为

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


不!您的假设是正确的。

删除此;很好。最后一个
p->commitsucide();
给出了未定义的行为,因为您已经在“第5行”中销毁了对象。

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


我不知道直接调用析构函数是否会导致未定义的行为,但用户定义的删除运算符不会被执行。

但是构造函数只被调用了3次,那么调用析构函数4次是如何合乎逻辑的呢?一旦类被调用,它就会爆炸(非常重要)数据成员。-称为“拒绝”第6行“应”给出内存访问错误(linux上为segfault),因为p指向的某个类的实例先前占用的地址空间“应”已被操作系统正确释放。或者析构函数是否延迟调用以删除?@slashmais:不,没有这样的保证,很少有实现是这样工作的。大多数实现都有“可用空间”的概念,这是操作系统分配给程序的内存,但不包含任何对象。从已删除对象回收的内存将回收到此“可用空间”,供将来的对象使用。是的,我想应该是这样的。解释第6行之所以成功,是因为空间还没有被回收。@slashmais第5行没有取消分配对象使用的内存。它只会破坏对象。正在使用的内存仍然被分配。因此
new(此)SomeClass;
是有效代码(它构造对象,但不分配内存)。第5行没有错,但必须先重建对象,然后才能使用delete释放所用内存。好的,如果不调用析构函数,就无法释放new分配的内存。