应该从成员方法中调用“删除此”吗?

时间:2009-12-07 18:23:42

标签: c++ self-destruction

我刚刚读了这篇article并希望得到大家的建议:

问:是否应该从成员方法中调用delete this;

12 个答案:

答案 0 :(得分:33)

通常这是一个坏主意,但它偶尔会有用。

只要在删除后不使用任何成员变量,它就是完全安全的,只要调用此方法的客户端理解它,就可以删除该对象。

这个有用的好例子是你的班级使用引用计数:

void Ref() {
  m_References++;
}

void Deref() {
  m_References--;
  if (m_References == 0) {
    delete this;
  }
}

答案 1 :(得分:12)

我认为这里确实有两个问题

可以从成员方法中有效地调用吗?

是。只要您对使用非常小心,这是合法的。

是否应删除在成员方法中使用的内容?

在非常具体的情况下,这是必要的。某些类型的智能指针例如使用delete this模式来终止指针。示例:CComPtr<>样式。

除了智能指针之外,应该避免它,除非你有充分的理由这样做。即便如此,我还是会仔细重新考虑我的情景,看看是否有办法绕过它。

答案 2 :(得分:11)

是的,您可以here's很好地解释何时以及为何

答案 3 :(得分:5)

是的,有一些情况很常见。

参考计数:

void release() 
{
  cnt--;
  if (cnt == 0) 
    delete this;
}

GUI编程。在某些框架中,当用户关闭窗口时,窗口通常会自行删除。

答案 4 :(得分:5)

准备好投票。

应该:不 技术上可以:是的 这是个好主意:绝对不是。
是否存在有用的情况:当然。如果你是C ++ foo非常强大。但大多数人并不那么好。所以,只有拥有一个与您一起工作的团队能够进行良好的代码审查,才能做到这一点。

<强>为什么
对象无法知道它已被动态分配(因此需要删除)或者是普通对象(因此不能删除),因此它如何决定应该删除的天气。因此,如果一个对象正在删除自己,那么在我看来,这个设计有一些严重的错误。

如果您有一个需要管理的对象,那么您应该编写一个单独的对象来进行管理(因此智能指针)。让对象做它擅长的事情,然后将对象的管理分解为另一个对象。

答案 5 :(得分:1)

并非没有充分的理由这样做。

问题在于,当你在成员函数中调用delete this时,你会产生令人讨厌的副作用 - 调用者仍然对你的实例有一个现在完全无效的引用。

这可能不是预期的行为,因此很容易导致令人讨厌的错误。

话虽如此,有时候这是合适的(我已经看到了一些内存管理方案,对于某些库,您可以在自己删除的类中显式创建方法 - 主要用于语言互操作性)。总的来说,我认为这是不好的做法。

答案 6 :(得分:1)

某些线程库在线程终止时实现自动销毁时会使用它。

void Thread::threadFunc()
{
    doRun();

    if(this->destroyOnExit == true)
        delete this;
}

答案 7 :(得分:1)

这通常用于MFC日。 IIRC窗口收到的最后一条消息是WM_NCDESTROY,此时你可以打电话给delete this,假设你当然是某种形式的虐待狂(尽管我认为MFC本身就是这样做的。)

答案 8 :(得分:0)

你可以做到这一点,只要它是成员函数中的最后一个元素,并且在返回之后你会忘记那个对象曾经存在过......但是,就像那篇文章那样问...你为什么要这样做?我不知道标准说的是什么,但它确实给我一个有趣的感觉:P

我想这有点像你应该使用GOTO声明,我个人有时会使用GOTO来清理C中的资源,特别是在特殊情况下。

我想知道共享的国家影响是什么(我知道的模糊陈述):P

答案 9 :(得分:0)

是。就像所有答案一样,如果您100%确定在调用delete this后不会使用该类的数据。

例如,在一个项目中:

void Test()
MyClass * Someclass = new MyClass;
SomeClass->DoYourThing();
SomeClass->KillYourself();
return;

void MyClass::DoYourThing() { return; }
void MyClass::KillYourself() {delete this;}

非常简单的解释,该项目使用delete this;作为该类型对象的内存管理的一部分;他们的构造函数将它们添加到正在使用的该类型的类的私有列表中,并在它们被销毁时从列表中删除,然后自行删除(这不是在析构函数中)。当程序到达其端点时,该类的任何对象都没有自行删除,然后所有对象都从静态成员函数调用KillYourself()等效函数CleanYourselves()

答案 10 :(得分:0)

  1. delete this无法从非成员函数调用:)
  2. 在你了解它的后果之前,这是一个坏主意。

答案 11 :(得分:0)

虽然与此主题没有直接关系,但我想澄清一下。 我被问到了一个问题:

int* a = new int ;
int* b = a ;
delete a;

现在下一个声明安全吗?

cout<<*b ;

我的回答: 删除a后, a 指向的位置已标记为删除,并且可以在任何时间将其分配给其他对象。因此,使用 b 访问该值并不安全,因为它可能在分配给其他对象后被修改。

注意:请不要贬低,这只是一个澄清