执行此代码时实际发生了什么?
class MyClass
{
MyClass()
{
//do something
delete this;
}
}
答案 0 :(得分:36)
事实证明,在这种特殊情况下,代码是合法的,但你远离未定义的行为。
C ++标准将对象的“生命周期”概念定义为其构造函数完成运行和析构函数开始运行之间的时间。它还明确指出(§3.8/ 5)
在对象的生命周期开始之前[...]如果对象是或者是具有非平凡析构函数的类类型,并且指针用作delete-expression的操作数,则该程序有未定义的行为。
由于对象的生命周期在构造函数完成之前尚未开始,因此在构造函数中,您引用的this
指针尚未开始其生命周期,在这种情况下尝试delete
它是完全安全的。但是,如果你为类编写析构函数,那么你将立即在这里遇到未定义的行为。
此外,如果更改构造函数以便在删除对象后尝试引用任何类的数据成员,则会得到未定义的行为。如果对象是在堆栈上分配的,那么您将获得未定义的行为。如果对象是静态的,您将获得未定义的行为。如果使用new
分配对象,则客户端将返回到它的指针将无效并使用它将导致未定义的行为。一般来说,不要尝试这样做!
答案 1 :(得分:0)
在这里我想了解的第一件事是为什么?您想做这样的事情吗?
构造函数是成员函数实际上正在构造对象的成员,并且您可以在对象完全构造后删除它,这就是为什么要做这样的事情-
class A
{
public:
A()
{
delete this;
}
~A()
{
}
};
导致未定义的行为。
此外,此外,如果您在析构函数中执行delete this
,这也是不正确的,因为对象本身正在受到破坏,并且在析构函数中执行delete this
会再次调用析构函数
class A
{
public:
A()
{
}
~A()
{
delete this; // calls the destructor again.
}
};
答案 2 :(得分:-1)
假设您的对象永远不会被任何东西继承,那么这应该可以正常工作。您的构造函数运行,然后立即调用析构函数。如果有任何东西继承了这个对象,它将会破坏,因为这个构造函数将在继承构造函数之前被调用。