intrusive_ptr使用基类进行引用计数并包含循环地狱

时间:2011-12-29 18:17:56

标签: c++ boost smart-pointers

我正在使用boost::intrusive_ptr作为我的引用计数智能指针。我正在使用这样的东西:

http://www.codeproject.com/KB/stl/boostsmartptr.aspx#intrusive_ptr%20-%20lightweight%20shared%20pointer

这似乎是一个好主意,因为它简化了新引用计数类的声明,只是继承它。问题来自前瞻性声明。有很多地方我想使用指向尚未在类定义中声明的类型的指针而且这是不可能的,因为处理引用计数的2个方法需要知道类型是否继承自CRefCounted。 / p>

如果我尝试在intrusive_ptr的声明之前包含依赖项,那就没问题,但是,我得到了很多循环包含。

你会如何处理这种情况?

2 个答案:

答案 0 :(得分:3)

我认为您可以使用intrusive_ptr_add_refintrusive_ptr_release的模板函数解决此问题,如下所示:

namespace boost {
  template<class T> void intrusive_ptr_add_ref(T* p) { ++(p->references) }
  template<class T>void intrusive_ptr_release(T* p) { 
    if (--(p->references) == 0) 
      delete p 
  }
};

您还需要调整CRefCounted中的好友声明

template class<T> friend void ::boost::intrusive_ptr_add_ref(T*);
template class<T> friend void ::boost::intrusive_ptr_release(T*);

使用这些声明,您可以在前向声明的类(如

)上使用intrusive_ptr
class A;
class B {
  ::boost::intrusive_ptr<A> _myPtr;
};
class A : public CRefCounted {
};

这个解决方案有一个缺点(理论上......),你为 add_ref的每个子类定义了一对release / CRefCounted函数,但我认为编译器无论如何都会选择使用内联,所以这可以忽略不计。

答案 1 :(得分:0)

我一直在使用类似的RefCounted基类,我开始想知道为什么我从来没有遇到过这个问题。这是因为我倾向于隐藏源文件中的实现细节。考虑以下B类头文件:

//File: B.h
#include <boost/intrusive_ptr.hpp>

class A;

class B
{
public:
    B();
    ~B();
    boost::intrusive_ptr<A> foo();
    void foo2(const boost::intrusive_ptr<A> p);
    boost::intrusive_ptr<A> p;
};

它有效,因为即使它使用intrusive_ptr,它也不需要实例化它的构造函数或析构函数。因此,它不需要知道关于A类的任何信息。

需要了解A的地方在源文件中。 (还有在调用foo / foo2的地方)。 B的构造函数和析构函数隐式调用intrusive_ptr&lt;一个&gt;的构造函数/析构函数,所以A的定义必须是可用的。

//File: B.cpp
#include "B.h"
#include "A.h" //Include header where A is defined.

B::B() { }
B::~B() { }

//Other member functions...

我不知道这对您的情况是否有帮助,但这是需要考虑的事情。 :)