30

当我执行这段代码时实际发生了什么?

class MyClass
{
    MyClass()
    {
        //do something
        delete this;   
    }
}
4

3 回答 3

41

注意:此答案适用于 C++03,并且似乎 C++11 及更高版本中的行为已更改,因此现在这是未定义的行为。

事实证明,在这种特殊情况下,代码是合法的,但是您远离未定义的行为。

C++03 标准将对象的“生命周期”定义为构造函数完成运行与析构函数开始运行之间的时间。它还明确指出(在 §3.8/5 中)

在对象的生命周期开始之前 [...] 如果对象将是或曾经是具有非平凡析构函数的类类型,并且指针用作删除表达式的操作数,则程序具有未定义的行为.

由于对象的生命周期直到构造函数完成才开始,因此在构造函数内部,this您引用的指针还没有开始它的生命周期,delete在这种情况下尝试它是完全安全的。但是,如果您为该类编写析构函数,那么您将立即在此处遇到未定义的行为。

此外,如果您更改构造函数以便在删除对象后尝试引用任何类的数据成员,您将获得未定义的行为。如果对象是在堆栈上分配的,您将获得未定义的行为。如果对象是静态的,您将获得未定义的行为。如果对象是使用 分配的new,那么客户端将返回到它的指针将是无效的,并且使用它会导致未定义的行为。一般来说,不要尝试这样做!

于 2011-03-14T19:52:57.623 回答
1

我想在这里理解的第一件事是你为什么要做这样的事情?

构造函数是一个成员函数,你的对象实际上是在其中构造的,一旦它完全构造,你就可以删除一个对象,这就是为什么要做这样的事情 -

class A
{
public:
    A()
    {
        delete this;
    }

    ~A()
    {
    }
};

导致未定义的行为

此外,补充一点,如果您delete this在析构函数中执行,这也是不正确的,因为对象本身正在经历破坏并且delete this在析构函数中执行将再次调用析构函数。

class A
{
public:
    A()
    {
    }

    ~A()
    {
        delete this;   // calls the destructor again. 
    }
};
于 2018-08-25T06:42:42.327 回答
-1

假设您的对象永远不会被任何东西继承,这应该可以正常工作。您的构造函数运行,然后立即调用析构函数。如果有任何东西继承了这个对象,它将中断,因为这个构造函数将在继承构造函数之前被调用。

于 2011-03-14T19:51:28.330 回答