如果一个成员函数尝试执行delete this;
,会发生什么情况,例如在以下类的构造函数中?
class A
{
public:
A(int);
~A();
int *pi;
}
A::A(int i)
{
delete this;
pi = new int(i);
}
A::~A()
{
delete pi;
}
如果一个成员函数尝试执行delete this;
,会发生什么情况,例如在以下类的构造函数中?
class A
{
public:
A(int);
~A();
int *pi;
}
A::A(int i)
{
delete this;
pi = new int(i);
}
A::~A()
{
delete pi;
}
这个 C++ FAQ 条目回答得很好,如下所述:
只要小心谨慎,对一个对象进行delete this
是可以的。
以下是我对“小心谨慎”的定义:
delete this
之后,你成员函数的其余部分不会触及该对象的任何部分(包括调用任何其他成员函数或接触任何数据成员)。delete this
之后,没有人会接触this指针本身。换句话说,你不能检查它,与另一个指针比较,将其与NULL比较,打印它,转换它或者对它执行任何操作。你在访问pi
之后进行了delete操作,违反了#3。
delete this
之后访问了成员变量pi
。 - SebastianRelease()
),这个技巧用于确保delete
使用分配对象时使用的相同内存分配器。当你输入它时,这肯定会引起某种警报,但至少有一个很好的理由使用这个结构。 - André Caron不好的事情。你可以删除这个;
但通常这是极其糟糕的想法,一旦完成,你就不能触及任何成员变量或成员函数。
delete this
,但前提是该实例是使用new
创建的,并且您不再访问该实例的任何成员。class A
{
public:
A(int);
int *pi;
};
A::A(int i)
{
pi = new int(i);
}
int main()
{
A* p = new A(10);
delete p;
p->pi = new int; //bad stuff
//or
A a(20);
delete &a; //bad stuff
a.pi = new int; //more bad stuff
}
更糟糕的是,当你delete this
时,pi
成员未初始化,导致析构函数试图删除一个悬空指针。
delete this
是明确定义的,尽管有点冒险。
delete this;
是可以的。但在构造函数中这样做以及在对象的字段之后访问它是未定义的行为。不幸的是,这通常不会导致处理器故障,只会导致堆破坏。 - Hans Passant