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

时间:2010-08-16 01:10:21

标签: 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超出范围时,通常只会出现原始实例。这留下了一个阴险的失败,等待那几次重复计数一次。

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

2 个答案:

答案 0 :(得分:6)

  

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

在这种情况下,您可以将它们专门用于InstrusiveBase继承类型。

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

  }

这很烦人,但它是宏观的,e..g:

 class A : InstrusiveBase
 { 
     ...
 }
 NO_SCOPED_PTR(A)
 NO_SHARED_PTR(A)

答案 1 :(得分:5)

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