在构造函数中“删除此”

时间:2011-03-14 19:44:52

标签: c++ constructor destructor delete-operator self-destruction

执行此代码时实际发生了什么?

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

3 个答案:

答案 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)

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