引用计数是诸多技术的基础,设计上基本如出一辙,chromium智能指针的设计原理也基本类似,不过更为精巧。
1) 抽象出引用计数的基类,避免模板膨胀的问题
![这里写图片描述](https://img-blog.csdn.net/20150328115112897)
2) 线程安全的引用计数
template <class T, typename Traits> class RefCountedThreadSafe;
// Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref count reaches 0. Overload to delete it on a different thread etc.
template<typename T>
struct DefaultRefCountedThreadSafeTraits {
static void Destruct(const T* x) {
// Delete through RefCountedThreadSafe to make child classes only need to be friend with RefCountedThreadSafe instead of this struct, which is an implementation detail.
RefCountedThreadSafe<T, DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
}
};
template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
public:
RefCountedThreadSafe() {}
void AddRef() const {
subtle::RefCountedThreadSafeBase::AddRef();
}
void Release() const {
if (subtle::RefCountedThreadSafeBase::Release()) {
Traits::Destruct(static_cast<const T*>(this));
}
}
protected:
~RefCountedThreadSafe() {}
private:
friend struct DefaultRefCountedThreadSafeTraits<T>;
static void DeleteInternal(const T* x) { delete x; }
DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
};
为避免线程问题,基于线程安全的引用计数提供了一种Traits模式,允许用户在引用计数为零时定制其行为,更好的实现用户的使用意图。比如,在引用计数达到0时,用户可能希望通知其它线程完成对象的清理,以保证对象的安全。这种策略在chromium的代码有较多的应用。
3、引用计数类的使用示例
class MyFoo : public base::RefCounted<MyFoo> {
...
private:
friend class base::RefCounted<MyFoo>;
~MyFoo();
};
注意:
1、使用时需要将析构函数设为私有函数,防止外部直接delete,使得对象的声明周期难以管理和控制。
2、将引用计数类声明为友元类,以便于引用计数类可以访问析构函数。