在工作中我们有一个基类,让我们称它为IntrusiveBase,它就像一个mixin,允许一个类存储在boost:intrusive_ptr中。也就是说,它为其子类提供了引用计数,并定义了intrusive_ptr_add_ref和intrusive_ptr_release重载。问题是,某人很容易忘记特定的子类继承自IntrusiveBase,然后将它存储在scoped_ptr或shared_ptr等其他智能指针中。这不起作用,因为,例如,无论引用的是什么,scoped_ptr都会在超出范围时删除该对象。我们在~IntrusiveBase中有一个断言,引用计数是1,但这并不是万无一失的,因为在scoped_ptr超出范围时,通常只会出现原始实例。这留下了一个阴险的失败,等待那几次重复计数不一次。
如果有人不小心这样做,有什么方法可以导致编译时失败?即使我必须为每个主要的智能指针类重复做一些事情,也是值得的。
答案 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。