“删除这个”有什么用?
-
22-07-2019 - |
题
今天,我看到了一些遗留代码。在析构函数中有这样的语句“delete this
”。我认为,这个调用将是递归的。为什么它有效?
我在Y!上快速搜索了一下,发现如果需要限制用户创建堆栈对象,我们可以将析构函数设为私有,并提供删除实例的接口。在提供的接口中,我们必须对该指针调用delete。
还有其他情况可以使用此类语句吗?
解决方案
“删除此”通常用于参考计算的对象。对于计数的Ref对象何时删除通常放置在对象本身的决定。这里是一个什么样的Release方法将如下所示的示例[1]。
int MyRefCountedObject::Release() {
_refCount--;
if ( 0 == _refCount ) {
delete this;
return 0;
}
return _refCount;
}
ATL COM对象是否是此模式的一个最好的例子。
[1]是我知道这不是线程安全。
其他提示
delete this
在析构函数中无效。它可以用在其他地方。但这很少是个好主意。这 wxWidgets
框架将它用于他们的线程类。它有一种模式,当线程结束执行时,它自动释放系统资源和自身(wxThread对象)。我发现这很烦人,因为从外部,你无法知道引用它是否有效 - 你不能调用像这样的函数 IsValid
不再存在,因为该对象不存在。这闻起来像是主要问题 delete this
, ,除了它不能用于非动态对象的问题之外。
如果您这样做,请确保您不再触摸任何数据成员,或在您以这种方式删除的对象上调用任何成员函数。最好将其作为非虚拟、受保护或私有函数中的最后一条语句。调用删除在虚拟和/或公共函数中也是有效的,但我会限制执行此操作的方法的可见性。
这 C++ 常见问题解答 有一个关于此的条目。关于我上述主张的 C++ 标准引用(3.8p5
):
在对象的生命周期开始之前但在分配该对象将占用的存储空间之后,或者在对象的生命周期结束之后并且在重用或释放该对象占用的存储空间之前,引用该存储空间的任何指针可以使用物体将要或曾经位于的位置,但只能以有限的方式使用。[...] 如果对象将是或曾经是具有非平凡析构函数的类类型,并且指针用作删除表达式的操作数,则程序具有未定义的行为。
当对象的析构函数开始执行时,生命周期结束。请注意,对于正在构造和销毁的对象,该段落之后的规则有例外(例如,您可以访问非静态数据成员),详细信息请参见 12.7
.
有。例如,自删除参考计数的对象(如JaredPar说)。 据我所知,他们都被认为是从长远来看,一个坏主意。
在一个双向链表,这是可能的,以除去一个节点而不引用任何外部结构,例如高电平“列表”对象。这使得合理为每个节点来处理其自己的解除分配(可能再加上一个互补的静态方法来处理从相同的内存池的初始分配)。在这种情况下,它可以使感为节点对象删除本身(当由用户请求)。
void RemoveAndDeallocate()
{
LinkedListNode *current_prev = prev, *current_next = next;
current_prev->next = current_next;
current_next->prev = current_prev;
delete this;
}
虽然,它也是合理的节点从一个列表中取消关联和链接到另一个列表中,没有任何解除分配存储器,所以它不是理想的单个删除操作无条件地释放内存。