我应该如何避免将“this”指针与智能指针结合使用?是否有任何设计模式/一般建议来解决这个问题?
我假设将两者结合起来是不行的,因为:
- 您将 native 指针传递给智能指针管理的对象,这首先就破坏了使用智能指针的意义,
- 如果在使用时将“this”指针包装在智能指针中,例如“return CSmartPtr(this);”,您已经有效地设置了管理同一对象的多个智能指针,因此第一个引用计数为零的智能指针将从另一个智能指针中销毁该对象,或者
- 如果您有一个成员变量保存 CSmartPtr(this) 的值以在这些情况下返回,那么它最终将是一个循环引用,导致引用计数始终为 1。
为了提供一些背景信息,我最近了解了将 STL 容器与对象相结合的负面影响(重复浅复制、使用基类容器时的切片等),因此我将这些的一些用法替换为我的代码带有指向对象的智能指针。一些对象使用“this”指针传递对自身的引用,这就是我陷入困境的地方。
我找到了smart pointers + “this” considered harmful?询问了一个有点类似的问题,但答案没有用,因为我没有使用 Boost。
编辑:我一直在做的一个(非常做作的)例子是
...::AddToProcessingList(vector<CSmartPtr> &vecPtrs)
{
vecPtrs.push_back(CSmartPtr(this));
}
最佳答案
可以将两者结合起来,但您始终需要清楚地了解所有权问题。一般来说,我遵循的规则是永远不要将原始指针转换为智能指针(具有所有权),除非您确定此时您正在获取该对象的所有权。这样做安全的时间应该是显而易见的,但包括以下内容:
- 您刚刚创建了该对象(通过
new
) - 您从某些外部方法调用中传递了该对象,其中语义显然是所有权之一(例如
添加
到容器类) - 该对象正在被传递给另一个线程
只要您遵守规则,并且不存在任何所有权不明确的情况,就不应该出现任何问题。
在上面的示例中,我可能会按如下方式查看它们:
- 您正在将 native 指针传递给智能指针管理的对象,这首先就破坏了使用智能指针的意义
在这种情况下,由于您正在传递 native 指针,因此根据我的规则,您可以假设您没有转移所有权,因此您无法将其转换为智能指针
- 如果在使用时将“this”指针包装在智能指针中,例如“return CSmartPtr(this);”,您已经有效地设置了管理同一对象的多个智能指针,因此第一个引用计数为零的智能指针将从另一个下销毁该对象
这显然是非法的,因为您已经说过该对象已经被其他某个智能指针拥有。
- 如果您有一个成员变量保存 CSmartPtr(this) 的值以在这些情况下返回,那么它最终将是一个循环引用,导致引用计数始终为 1。
如果某些外部代码隐式拥有该成员变量,那么这实际上是可以管理的 - 该代码可以在释放对象之前的某个时刻调用某种 close()
方法。显然,根据反射,外部代码拥有该对象,因此它本身应该有一个智能指针。
boost 库(我接受你说过你没有使用它)使此类问题更容易管理,因为它按照不同类型的所有权(作用域、共享、弱等)划分了智能指针库)。
关于c++ - "this"指针和智能指针是否应该混合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1365206/