“删除这个”是否安全?

时间:2009-02-15 02:25:17

标签: c++ runtime-error self-destruction

在我最初的基础测试中,这样做是完全安全的。但是,让我感到震惊的是,稍后在this s delete的函数中尝试操作this可能是运行时错误。这是真的,delete this通常是否安全?或者只有某些安全的情况?

10 个答案:

答案 0 :(得分:46)

delete this是合法的并且可以达到您所期望的效果:它会调用您的类的析构函数并释放底层内存。 delete this返回后,您的this指针值会更改,因此它现在是一个悬空指针,将被取消引用。这包括使用类的成员变量进行隐式解除引用。

通常在引用计数类中找到,当ref-count递减为0时,DecrementRefCount() / Release() /无论成员函数调用delete this

出于多种原因,

delete this通常被视为非常糟糕的形式。在delete this之后很容易意外访问成员变量。来电者代码可能无法实现您的对象具有自毁功能。

此外,delete this是一种“代码味道”,您的代码可能没有对象所有权的对称策略(谁分配和删除谁)。 一个对象无法用new分配自己,所以调用delete this意味着A类正在分配一个对象,但是B类稍后将其释放[self]。

答案 1 :(得分:16)

删除“this”是安全的,只要它基本上是方法中的最后一个操作。事实上,有几个专业级别的API会这样做(参见ATL的CComObject实现)。

唯一的危险是在调用“删除此”后尝试访问任何其他成员数据。这当然不安全。

答案 2 :(得分:13)

删除这是完全合法的,正如其他人已经提到的那样。尚未提及的另一个原因是冒险的 - 您假设该对象已在堆上分配。这可能难以保证,尽管在引用计数实现的情况下通常不是问题。

答案 3 :(得分:13)

但不要在析构函数中执行此操作!

答案 4 :(得分:6)

正如其他人所说,删除这是一个有效的习惯用法,但为了安全起见,你必须确保对象永远不会在堆栈上实例化。

这样做的一种方法是使构造函数和析构函数都是私有的,并通过类工厂函数强制创建对象,该函数在堆上创建对象并返回指向它的指针。类工厂可以是静态成员函数或友元函数。然后可以通过执行“删除此操作”的对象上的Delete()方法完成清理。 COM对象基本上以这种方式工作,除此之外它们是引用计数,当引用计数减少到零时发生“删除此”。

答案 5 :(得分:3)

是。应该完全没问题。 “这个”只是一个指针。任何指针都可以用于删除。有关如何删除对象的信息包含在堆记录中。这就是IUnknown :: Release()通常在COM对象中实现的方式。

答案 6 :(得分:3)

如果您要删除要删除的对象的子类,则删除此选项可能会导致出现问题。记住施工从上到下开始,从下到上开始删除。因此,如果删除它位于层次结构的中间,则基本上会丢失此特定类下面的所有对象。

删除它在实现引用计数对象时非常方便,其中一个示例是COM类。

答案 7 :(得分:2)

Read进行类似的讨论。您的理解是正确的,因为它确实有效,需要,并且可能很危险,因为您之后无法访问它。

答案 8 :(得分:2)

法律是
安全否

答案 9 :(得分:-2)

如果从基类继承并在基类函数中删除它,则使用派生类指针将导致崩溃。 E.g:

class Base
{

    virtual void Release()
    {
        delete this;
    }

}

class Derived : public Base
{

    void Foo()
    {
        ...
    }

}

main()
{

    Base *ptrDerived = new Derived();
    ptrDerived->release();
    ptrDerived->Foo() //Crash

}