引用计数型指针类的一个实现

来源:互联网 发布:java中的接口的实现 编辑:程序博客网 时间:2024/04/28 15:11

这是一段引用计数指针的代码,目标是一个轻量级的、高效率的实现,避免通常实现中的频繁的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_type ins_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

原创粉丝点击