今天,我看到了一些遗留代码.在析构函数中有一个类似" 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
除了不能用于非动态对象的问题之外,这就像是主要问题.
如果这样做,请确保不要触摸任何数据成员,或者在您删除的对象上再调用任何成员函数.最好将它作为非虚拟,受保护或私有函数中的最后一个语句.调用delete也在虚拟和/或公共函数中有效,但我会限制方法的可见性.
在C++ FAQ有关于一个条目.关于我上述索赔的C++标准报价(3.8p5
):
在对象的生命周期开始之前但是在对象将占用的存储之后,或者在对象的生命周期结束之后以及在重用或释放对象占用的存储之前,任何指向存储的指针之前可以使用对象将位于或位于的位置,但仅限于有限的方式.[...] 如果对象将是或具有非平凡析构函数的类类型,并且指针用作delete-expression的操作数,则程序具有未定义的行为.
生命周期在对象的析构函数开始执行时结束.注意也有例外该段在建与破坏对象后传来的规则(你被允许访问非静态数据成员,例如),在详细12.7
.