我一直在为一个设计用作链表中的节点的类做一些工作,我想我会给类自己的删除功能而不是管理类这样做。所以基本上它是这样的:
void Class::Delete() {
//Some cleanup code before deleting the object
delete this;
}
现在我已经测试了这个并且看起来工作正常,但是我在过去遇到了一个问题,即对象已经在运行代码的中间,被删除,然后显然是通过尝试使用一个程序来破坏程序不再存在的对象。
由于“删除这个”就在函数的末尾,它显然退出了函数并且工作正常,但这种做法是不是一个坏主意?如果我不小心,这会不会在我的脸上爆炸?
答案 0 :(得分:21)
FAQlite很好地回答了这个问题:
只要你小心,就可以了 自杀的对象(删除 这一点)。
以下是我如何定义“小心”:
- 你必须绝对100%肯定这个对象 通过new分配(不是通过new [],也不是 通过放置新的,也不是本地对象 在堆栈上,也不是全局的,也不是 另一个对象的成员;但是平淡无奇 普通新)。
- 您必须绝对100%肯定您的会员 功能将是最后一个成员 在此对象上调用的函数。
- 你必须绝对100%肯定你的其余部分 成员函数(删除之后) line)不触及任何一件 对象(包括调用任何其他对象 成员函数或触摸任何数据 成员)。
- 你必须绝对100%肯定没有人接触过 之后的这个指针本身 删除这一行。换句话说,你 一定不要检查它,比较它 另一个指针,将其与NULL进行比较, 打印,投射,做任何事情 它。
醇>当然,通常的警告适用于 你的this指针是a的情况 指向基类的指针 有一个虚拟的析构函数。
基本上,您需要像对delete
任何其他指针一样谨慎。但是,与明确声明的指针相比,有更多的区域可能会出现成员函数自杀的问题。
答案 1 :(得分:6)
使用delete this
是一个坏主意,如果一个人不确定陷阱和&解决他们。
一旦调用delete this
,将调用对象的析构函数,并释放动态分配的内存。
如果未使用new
分配对象,则为Undefined behaviour
如果在delete this
之后访问了对象的任何数据成员或虚函数,则行为将再次为Undefined Behavior
。
可能最好避免delete this
给出上述内容。
答案 2 :(得分:4)
它实际上是一种常用的习惯用语,与任何删除一样安全。如
对于所有删除,您必须确保没有其他代码尝试
访问该对象,您必须确保该对象是
动态分配。然而,通常,后者不是a
问题,因为成语仅与具有a的对象相关
生命周期由对象的语义决定,而这些对象是
总是动态分配。找到了所有的指针
对象可能是一个问题(是否使用delete this
);通常情况下,
某种形式的观察者模式将用于通知所有感兴趣的人
对象将不复存在的各方。
答案 3 :(得分:2)
在C ++中这样做的惯用方法是将清理代码放在析构函数中,然后在删除对象时自动调用它。
Class::~Class() {
do_cleanup();
}
void ManagingClass::deleteNode(Class* instance) {
delete instance; //here the destructor gets called and memory gets freed
}
答案 4 :(得分:1)
有一种简单的方法可以做同样的事情,不涉及未定义的行为:
void Class::Delete() {
//Some cleanup code before deleting the object
std::auto_ptr delete_me(this);
}