C++ 应否";这";指针和智能指针可以混合使用吗?
如何避免将“this”指针与智能指针结合使用?有没有关于解决这个问题的设计模式/一般建议 我认为两者结合是不可能的,因为:C++ 应否";这";指针和智能指针可以混合使用吗?,c++,stl,smart-pointers,C++,Stl,Smart Pointers,如何避免将“this”指针与智能指针结合使用?有没有关于解决这个问题的设计模式/一般建议 我认为两者结合是不可能的,因为: 您正在传递一个指向智能指针管理对象的本机指针,该对象首先无法使用智能指针 如果在使用时将“this”指针包装在智能指针中,例如“return CSmartPtr(this);”,则可以有效地设置多个管理同一对象的智能指针,以便第一个引用计数为零的指针将从另一个指针下销毁该对象,或者 在这些情况下,如果有一个成员变量持有CSmartPtr(this)的值以返回,那么它最终将是
...::AddToProcessingList(vector<CSmartPtr> &vecPtrs)
{
vecPtrs.push_back(CSmartPtr(this));
}
…::AddToProcessingList(向量和向量ptrs)
{
向量。推回(CSmartPtr(此));
}
大多数智能指针框架都提供了一种解决方法。例如,Boost.SmartPtr从这个CRTP类中提供了一个enable\u shared\u,您可以使用它作为基类,然后您可以确保您的共享指针不会导致指向同一对象的两个指针。可以将这两个指针结合起来,但您始终需要清楚地记住所有权问题。一般来说,我遵循的规则是永远不要将原始指针转换为智能指针(具有所有权),除非您确定在该点上获得了对象的所有权。这样做安全的时间应该是显而易见的,但包括:
您刚刚创建了对象(通过new
)
从某个外部方法调用传递对象,其中语义显然是所有权(例如add
到容器类)
对象正在传递给另一个线程
只要您遵守规则,并且没有任何不明确的所有权情况,那么就不会出现任何问题
在您上面的示例中,我可能会如下所示:
您正在传递一个指向智能指针管理对象的本机指针,这首先会破坏使用智能指针的意义
在本例中,由于您正在传递本机指针,根据我的规则,您可以假定您没有转移所有权,因此无法将其转换为智能指针
如果在使用时将“this”指针包装在智能指针中,例如“return CSmartPtr(this);”,则可以有效地设置多个管理同一对象的智能指针,以便引用计数为零的第一个指针将从另一个指针下销毁该对象
这显然是非法的,因为您已经说过该对象已经由其他智能指针拥有
在这些情况下,如果有一个成员变量持有CSmartPtr(this)的值以返回,那么它最终将是一个循环引用,导致引用计数始终为一
如果某些外部代码隐式拥有成员变量,则实际上可以管理该变量-此代码可以在释放对象之前的某个点调用某种close()
方法。显然,经过反思,该外部代码拥有该对象,因此它本身应该有一个智能指针
boost库(我承认您说过您没有使用它)使此类问题更易于管理,因为它将智能指针库划分为不同的所有权类型(作用域、共享、弱等)。解决此问题的一个相当健壮的解决方案是使用侵入式智能指针。要实例化RefCountedPtr
,T应该从RefCount派生。这允许从This
构造RefCountedPtr
,因为This->RefCount::m_count
保存确定生存期的单个计数器
缺点:当您将对象放在堆栈上时,您有一个未使用的RefCount。您能否提供示例代码作为您尝试执行操作的概念证明?我添加了一个人为的示例。我发现很难用一段代码来描述它,但我尽了最大努力。显然,这段代码不是最优的,它的设计目的是最清楚地展示问题。