Angle项目RefCountObject.h中临时指针作用及最佳实践的疑问
关于RefCountObject中set方法的疑问解答
一、临时指针避免析构时仍被引用的原理
先看反例:如果不使用临时指针,改成先调用release再更新mObject,代码逻辑会变成这样:
// 错误示例:先释放再赋值 if (mObject != nullptr) { reinterpret_cast<RefCountObject<ContextType, ErrorType> *>(mObject)->release(context); } mObject = newObject;
假设mObject指向的旧对象当前引用计数为1,调用release后计数会降到0,触发对象的析构函数。这时候问题来了:在析构函数执行期间,mObject仍然指向这个正在被销毁的对象。
如果析构函数内部有逻辑依赖于“自身被某个外部指针持有”的状态,或者在析构过程中,当前类的其他成员函数(比如被析构函数间接调用)不小心访问了mObject,就会出现访问已销毁内存的未定义行为,或者逻辑上认为对象还存活但实际已经被回收的矛盾。
而原代码的做法是:
- 先把旧对象地址存到临时变量
oldObject - 立刻将
mObject更新为新对象newObject - 最后对
oldObject调用release
这样一来,在调用release触发析构之前,当前类的mObject已经不再指向旧对象了。即使旧对象被销毁,当前类内部也没有任何成员指针还残留对它的引用,彻底避免了析构时对象仍被自身持有引用的问题。
二、这种做法是否属于C++最佳实践
这是引用计数类资源管理中的标准安全操作,属于C++资源管理的最佳实践之一,核心思路是**“先切换指向,再释放旧资源”**,本质上是避免资源释放过程中出现悬空指针或无效引用。
在智能指针的实现(比如std::unique_ptr的reset方法)中,也遵循类似逻辑:先保存旧指针,更新内部指针为新值,再销毁旧指针指向的资源。这种模式能有效避免资源释放时的竞态条件和悬空引用问题,是编写可靠引用计数类的必要步骤。
内容的提问来源于stack exchange,提问作者huylq
相关产品推荐
相关产品推荐

