"delete this"是个坏主意吗?

Is "delete this" a bad idea?

本文关键字:delete this      更新时间:2023-10-16

可能的重复项:
delete this安全吗?

我一直在对一个旨在充当链表中节点的类做一些工作,我想我会给类它自己的删除函数,而不是管理类来做这件事。所以基本上是这样的:

void Class::Delete() {
    //Some cleanup code before deleting the object
    delete this;
}

现在我已经对此进行了测试,它似乎工作正常,但是我过去遇到了一个问题,即对象一直在运行代码的过程中被删除,然后显然通过尝试使用不再存在的对象使程序崩溃。

由于"删除这个"就在函数的末尾,它显然退出了函数并且工作正常,但这种做法根本不是一个坏主意吗?如果我不小心,这会在我脸上爆炸吗?

FAQlite很好地回答了这个问题:

只要你小心,没关系 自杀对象(删除 这(。

以下是我对"小心"的定义:

  1. 您必须绝对 100% 肯定此对象是 通过新分配(不是由新[]分配,也不是由新分配 通过放置新对象,也不是本地对象 在堆栈上,也不是全局的,也不是 另一个对象的成员;但平淡无奇 普通新(。
  2. 您必须绝对 100% 肯定您的会员 函数将是最后一个成员 在此对象上调用的函数。
  3. 你必须绝对 100% 肯定你的其余部分 成员函数(删除此函数后 行(不碰任何一块 对象(包括调用任何其他 成员函数或触摸任何数据 成员(。
  4. 你必须绝对 100% 肯定没有人碰 此指针本身在 删除此行。换句话说,你 一定不能检查它,把它与 另一个指针,将其与 NULL 进行比较, 打印它,铸造它,做任何事情 它。

当然,通常的警告适用于 此指针为 指向基类的指针(如果不这样做( 有一个虚拟析构函数。

基本上,您需要像delete任何其他指针一样小心。但是,与显式声明的指针相比,成员函数自杀时可能会出现更多问题。

如果

不确定陷阱并解决它们,那么使用delete this是一个坏主意。

调用delete this将调用对象的析构函数,并释放动态分配的内存。

如果对象不是使用 new 分配的,它将是一个Undefined behaviour
如果在delete this后访问了对象的任何数据成员或虚函数,则行为将再次Undefined Behavior

可能,鉴于上述情况,最好避免delete this

它实际上是一个常见的成语,并且与任何删除一样安全。 如对于所有删除,您必须确保没有进一步的代码尝试访问该对象,并且必须确保该对象是动态分配。 然而,通常情况下,后者不是问题,因为该习语仅与具有生存期由对象的语义决定,此类对象是始终动态分配。 也找到所有指针对象可能是一个问题(无论是否使用delete this(;通常某种形式的观察者模式将用于通知所有感兴趣的人对象将不复存在的当事方。

在C++中执行此操作的惯用方法是将清理代码放在析构函数中,然后在删除对象时自动调用它。

Class::~Class() {
    do_cleanup();
}
void ManagingClass::deleteNode(Class* instance) {
    delete instance; //here the destructor gets called and memory gets freed
}

有一种简单的方法可以做同样的事情,不涉及未定义的行为:

void Class::Delete() {
    //Some cleanup code before deleting the object
    std::auto_ptr delete_me(this);
}