如何防止在其他智能指针中存储基于intrusive_ptr的类

SCF*_*nch 2 c++ boost smart-pointers

在工作中我们有一个基类,我们称之为IntrusiveBase,它就像mixin一样,允许将类存储在boost:intrusive_ptr中.也就是说,它为其子类提供了引用计数,并定义了intrusive_ptr_add_ref和intrusive_ptr_release重载.问题是,某人很容易忘记特定的子类继承自IntrusiveBase,然后将它存储在scoped_ptr或shared_ptr等其他智能指针中.这不起作用,因为,例如,无论引用的是什么,scoped_ptr都会在超出范围时删除该对象.我们在~IntrusiveBase中有一个断言,引用计数是1,但这并不是万无一失的,因为在scoped_ptr超出范围时,通常只会出现原始实例.不是一个.

如果有人不小心这样做,有什么方法可以导致编译时失败?即使我必须为每个主要的智能指针类重复做一些事情,也是值得的.

Log*_*ldo 6

即使我必须为每个主要的智能指针类重复做一些事情,也是值得的.

在这种情况下,您可以在InstrusiveBase继承类型上对它们进行专门化.

  namespace boost
  {
    template<>
    class scoped_ptr<InstrusiveBaseSubclass> { }; // scoped_ptr<InstrusiveBaseSubClass> p(new InstrusiveBaseSubClass) won't compile, neither will p->, p.get() etc.

  }
Run Code Online (Sandbox Code Playgroud)

这很烦人,但它具有宏观能力,例如:

 class A : InstrusiveBase
 { 
     ...
 }
 NO_SCOPED_PTR(A)
 NO_SHARED_PTR(A)
Run Code Online (Sandbox Code Playgroud)


Log*_*ldo 5

另一种选择是为这些类重载new和delete并使delete成为私有或受保护.然后instrusive_ptr_release可以成为友元函数或类似技术,用于在ref计数降为零时实际调用delete.