2010-08-16 17 views
2

在工作中,我们有一个基类,我们称之为IntrusiveBase,它的作用类似于mixin,以允许类存储在boost:intrusive_ptr中。也就是说,它为其子类提供引用计数并定义intrusive_ptr_add_ref和intrusive_ptr_release重载。问题在于,有人忘记了一个特定的子类是从IntrusiveBase继承而来的,然后将它们存储在一些其他智能指针中,比如scoped_ptr或shared_ptr。这不起作用,因为,例如,scoped_ptr会在对象超出范围时删除该对象,无论引用计数是多少。我们在~IntrusiveBase中有一个断言,ref的数目是1,但这不是万无一失的,因为在scoped_ptr超出范围时,通常最终只会是原始实例。这就等于发生了几次这样的阴险故障,其中参考数是而不是之一。如何防止在其他智能指针中存储基于intrusive_ptr的类

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

+0

您应该允许使用scoped_ptr - 任何使用scoped_ptr的人都可能理解该单个代码块应该拥有该类的实例。 – 2010-08-16 01:54:57

+0

'intrusive_ptr'作为一个基类总是很烦人。想想可怕的钻石继承层次结构......这就是为什么'unique_ptr','scoped_ptr'和'shared_ptr'如此受欢迎。 – 2010-08-16 12:07:09

回答

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) 
5

另一种选择是重载new和delete这些类,并删除私人或保护。 instrusive_ptr_release然后可以作为朋友函数或类似的技术,用于在ref计数降到零时实际调用删除。

+0

所以,我尝试了这个,但它似乎并没有工作。我遇到了这个问题:http://stackoverflow.com/questions/1820069/public-operator-new-private-operator-delete-getting-c2248-can-not-access-priva – SCFrench 2010-08-19 00:52:35