我刚刚读了这篇article并希望得到大家的建议:
问:是否应该从成员方法中调用delete this;
?
答案 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)
delete this
无法从非成员函数调用:)答案 11 :(得分:0)
虽然与此主题没有直接关系,但我想澄清一下。 我被问到了一个问题:
int* a = new int ;
int* b = a ;
delete a;
现在下一个声明安全吗?
cout<<*b ;
我的回答: 删除a后, a 指向的位置已标记为删除,并且可以在任何时间将其分配给其他对象。因此,使用 b 访问该值并不安全,因为它可能在分配给其他对象后被修改。
注意:请不要贬低,这只是一个澄清