“删除这个”在构造函数中

发布于 2024-10-21 15:29:01 字数 142 浏览 4 评论 0原文

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

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

What actually happen when I execute this code?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水溶 2024-10-28 15:29:01

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

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

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

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

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

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

Note: This answer applies to C++03, and it seems like the behavior was changed in C++11 and higher so that this is now undefined behavior.

It turns out that in this particular case the code is legal, but you're ε-away from undefined behavior.

The C++03 standard defines the notion of the "lifetime" of an object to be the time between which its constructor has finished running and when the destructor starts running. It also explicitly states (in §3.8/5) that

Before the lifetime of an object has started [...] If the object will be or was of a class type with a non-trivial destructor, and the pointer is used as the operand of a delete-expression, the program has undefined behavior.

Since an object's lifetime has not started until the constructor finishes, inside the constructor the this pointer you've referred to has not begun its lifetime, trying to delete it in this case is totally safe. However, if you write a destructor for the class, then you'll immediately run into undefined behavior here.

In addition, if you change the constructor so that you try referencing any of the class's data members after you delete the object, you'll get undefined behavior. If the object was allocated on the stack, you'll get undefined behavior. If the object was static, you'll get undefined behavior. If the object was allocated using new, then the pointer the client will get back to it will be invalid and using it will result in undefined behavior. In general, don't try doing this!

芸娘子的小脾气 2024-10-28 15:29:01

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

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

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

    ~A()
    {
    }
};

会导致未定义的行为

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

class A
{
public:
    A()
    {
    }

    ~A()
    {
        delete this;   // calls the destructor again. 
    }
};

The first thing that I want to understand here is WHY do you want to do something like this?

Constructor is a member function where your object is actually getting constructed and you can delele an object once it is fully constructed, that's why doing somrthing like this -

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

    ~A()
    {
    }
};

results in an undefined behavior.

Also, to add to this, if you perform delete this in the destructor, it is also not correct since the object is itself undergoing the destruction and doing delete this in the destructor will again call the destructor.

class A
{
public:
    A()
    {
    }

    ~A()
    {
        delete this;   // calls the destructor again. 
    }
};
初见你 2024-10-28 15:29:01

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

Assuming your object is never inherited by anything this should work fine. Your constructor runs and then the destructor is immediately called. If anything inherits this object it will break since this constructor will be called before the inheriting constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文