如何实现引用计数型指针类?
这是一段引用计数指针的代码,目标是一个轻量级的、高效率的实现,避免通常实现中的频繁的new/delete引用计数的存储空间。
一些说明:
Q:为什么在ref_count的release中delete对象,而不是让外部的ref_count_ptr来释放对象?
A:将对象的销毁放到比较高的层次上,从而使得程序员更容易控制对象的销毁策略,看上去是非常有诱惑力的。但是,问题在于,我们使用ref_count_ptr时,意味着我们需要将这个对象传来传去。这个过程可能跨越不同的module.不同module之间的存储管理可能是完全不同的,如果混用,将导致不可预料的行为.
Q:ref_count_ptr为什么没有提供协变?
A:考虑到assembler的特性,父类和子类被组装之后,assembler<>的裸指针也已经失去了相互转换的能力,因此,在这里提供协变没什么意义。
#ifndef REFCOUNT_H
#define REFCOUNT_H
#include "contract.h"
namespace nice
{
//通常,应该作为一种策略被组合到对象上,而不是继承树的基类
//因此virtual public继承常常是必要的.
struct non_ref_count{};
class ref_count
//被组合对象将通过delete来释放,因此,对象的分配必须能够满足此要求。
//这在1.使用allocator策略时,可能导致问题。
// 2.不可以使用stack对象
// 3.不可是数组成员,本身也不可以是数组,但可以是容器
{
public://publishing interface
ref_count() : count_(0){}
virtual ~ref_count() {}
//default ctor && assignment
int add_ref()
{
return ++count_;
};
int release()
{
int tmp = --count_;
if (tmp == 0)
delete this;
return tmp;
}
public://queries
int count() const
{
return count_;
}
private:
int count_;
};
template<typename _ins_type>
class ref_count_ptr
{
public:
typedef _ins_typeins_type;
ref_count_ptr() : obj_(0){};
~ref_count_ptr()
{
release();
}
ref_count_ptr(const ref_count_ptr& rhs) : obj_(rhs.obj_)
{
inc();
}
ref_count_ptr& operator=(const ref_count_ptr& rhs)
{
refrence(rhs.obj_);
return *this;
}
ins_type* refrence() const
{
return obj_;
}
void refrence(ins_type* obj)
{
if (obj == obj_)
return;
release();
obj_ = obj;
inc();
}
ins_type* operator->() const
{
pre_condition(!is_null(), "derefrence Null pointer");
return obj_;
}
ins_type& operator*() const
{
pre_condition(!is_null(), "derefrence Null pointer");
return *obj_;
}
bool is_null() const
{
return obj_ == 0;
}
#define MEMBER_OPE(ope)/
inline bool operator ope (const ref_count_ptr& rhs) const/
{/
return obj_ ope rhs.obj_;/
}
MEMBER_OPE(==)
MEMBER_OPE(!=)
MEMBER_OPE(<)
MEMBER_OPE(<=)
MEMBER_OPE(>)
MEMBER_OPE(>=)
#undef MEMBER_OPE
private:
void release()
{
obj_ != 0 && obj_->release();
}
void inc()
{
if (obj_ != 0)
obj_->add_ref();
}
ins_type* obj_;
};
template<typename ins_type, typename ref_count_ = ref_count>
class assembler : public ins_type
, public ref_count_//没有virtual, 因此,派生需小心,不要再引入ref_count
//不使用virtual是为了效率,
{
public:
assembler(){}
assembler(const ins_type& obj, const ref_count_& ref = ref_count_())
: ins_type(obj), ref_count_(ref)
{}
assembler(const assembler& rhs) : ins_type(rhs), ref_count_()
{}
assembler& operator=(const assembler& rhs)
{
ins_type::operator=(rhs);
return *this;
}
};
} //namespace nice
#endif //end REFCOUNT_H guard
本文地址:http://www.45fan.com/a/question/70029.html