我应该如何避免将“this”指针与智能指针结合使用?有没有关于解决这个问题的设计模式/一般建议?
我假设将两者结合起来是一个禁忌:
为了给出一些上下文,我最近了解了将STL容器与对象结合起来的负面影响(重复浅层复制,使用基类容器时切片等),所以我在替换它们的一些用法我的代码与智能指针对象。一些对象使用“this”指针传递对自己的引用,这就是我被困住的地方。
我发现smart pointers + “this” considered harmful?问了一个类似的问题,但答案没有用,因为我没有使用Boost。
编辑:一个(非常人为的)我正在做的事情的例子是
...::AddToProcessingList(vector<CSmartPtr> &vecPtrs)
{
vecPtrs.push_back(CSmartPtr(this));
}
答案 0 :(得分:2)
大多数智能指针框架都提供了一种方法。例如,Boost.SmartPtr提供了一个enable_shared_from_this<T>
CRTP类,您可以将其用作基类,然后可以确保共享指针不会产生指向同一对象的两个指针。
答案 1 :(得分:2)
可以将两者结合起来,但是您始终需要清楚地了解所有权问题。通常,我遵循的规则是永远不会将原始指针转换为智能指针(具有所有权),除非您确定在此时获取对象的所有权。这是安全的时间应该是显而易见的,但包括:
new
)add
到容器类)只要您遵守规则,并且您没有任何模棱两可的所有权情况,那么就不会出现任何问题。
在上面的示例中,我可能会按如下方式查看它们:
在这种情况下,由于您传递的是本机指针,您可以根据我的规则假设您没有转移所有权,因此您无法将其转换为智能指针
这显然是非法的,因为你已经说过该对象已经被其他智能指针所拥有。
如果某些外部代码隐式拥有成员变量,这实际上可以被管理 - 这个代码可以在对象被释放之前的某个时刻调用某种close()
方法。显然在反思时,外部代码拥有对象,所以它本身应该有一个智能指针。
boost库(我接受你说你没有使用)使这些问题更易于管理,因为它将智能指针库与不同类型的所有权(scoped,shared,weak等)分开)。
答案 2 :(得分:1)
这个问题的一个相当强大的解决方案是使用侵入式智能指针。要实例化RefCountedPtr<T>
,T应该来自RefCount。这允许从RefCountedPtr<T>
构建this
,因为this->RefCount::m_count
包含确定生命周期的单个计数器。
下行:当您将对象放入堆栈时,您有一个未使用的RefCount。