我使用boost::intrusive_ptr
作为我的引用计数智能指针。我用的是这样的:
http://www.codeproject.com/KB/stl/boostsmartptr.aspx intrusive_ptr % 20 - % 20轻量级% 20共享% 20指针
这似乎是一个好主意,因为它简化了新的引用计数类的声明,只是从它继承。问题来自于前向声明。有很多地方,我想使用指针的类型尚未在类定义中声明,这是不可能的,因为处理refcount的两个方法需要知道类型是否继承自crefcount。
如果我尝试在intrusive_ptr声明之前包含依赖关系,这是可以的,但随后,我得到了很多循环包含。
你会如何处理这种情况?
我认为您可以使用intrusive_ptr_add_ref
和intrusive_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 {
};
这个解决方案有缺点(理论上…),你为每个 CRefCounted
的子类定义一对add_ref
/release
函数,但我认为编译器无论如何都会选择使用内联,所以这可以忽略。
我一直在使用一个类似的refcounts基类很多,我开始想知道为什么我从来没有这个问题。这是因为我倾向于在源文件中隐藏实现细节。考虑下面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的构造函数/析构函数,因此A的定义必须可用。
//File: B.cpp
#include "B.h"
#include "A.h" //Include header where A is defined.
B::B() { }
B::~B() { }
//Other member functions...
我不知道这对你是否有帮助,但这是值得考虑的事情。:)