您的位置:首页 > 移动开发 > Objective-C

对象引用计数

2006-03-20 21:15 447 查看
  引用计数是为了节省空间的目的,在一个类A中,我们可以包含一个类B对象的指针,从而如果类A的不同实例都有同一的类B对象,那么这些实例中的B对象指针就可以指向同一个B对象.
  下面是对象引用计数的一个粗略的实现,同时如果要达到引用计数的目的,必须有些限制条件.

第1:类A必须有reference_count<int>类的一个对象
第2:要为char*的类型提供特化版本
第3:要取得引用的对象,我们必须提供自己的一个方法调用reference_count<int>对象的getObject()
   方法.
第4:如果对象引用的频率不高,或者对象不是很大,那么可能达不到空间节省的目的.

在下面的程序中还有不少细节没考虑,比如读和写的操作区别等等,具体参考more effective c++

#include <iostream>
#include <new>
using namespace std;
#ifndef       REFRENCECOUNT_HPP
#define       REFRENCECOUNT_HPP

/*this class is used to store the count of the reference,this class is transparent for you*/
template <class ReferenceObject>  class reference_base
{
 /*declare typedef*/
public:
 typedef  ReferenceObject  object;
 typedef  object           *object_ptr;
   
private:
  int  count;
  bool  is_shared;   /*when is_shared is false,the instantiation can not be count again*/
  object_ptr  obj;   /*which instantiation we count*/

public:
 reference_base(object_ptr pobj):count(1),is_shared(true)
 {   
  obj =static_cast<object_ptr>(malloc(sizeof(object)));
  memcpy(obj,pobj,sizeof(object));
 }
   reference_base(const reference_base& pobj):count(1), is_shared(true)
 {
  obj =static_cast<object_ptr>(malloc(sizeof(object)));
  memcpy(obj,pobj.obj,sizeof(object));
 
 }

 reference_base& operator =(const reference_base&)
 {
    return *this;
 }

  void increase_reference()
 {
      cout<<"before increase count is"<<count<<endl;
   ++count;
 }
  
 void decrease_reference()
 {
   cout<<"before decrease count is"<<count<<endl;
  if(--count == 0)
   delete obj;
 }
  
 bool is_shareable()
 {
  return is_shared;
 }

   /*when we change the flag, we have no opportunity to change the flag back*/
 void set_unshare()
 {
  is_shared=false;
 }

 int get_count()
 {
  return  count;
 }

    object_ptr getObject()
 {
    return obj;
 }

 ~reference_base()
 {    
   delete  obj;
 }
};

/*this class give us help to do increase_reference and decrease_reference
 this template class have only a template argument. ReferenceObject means the type of
 the  being counted object.
*/
template <class ReferenceObject>  class reference_count
{
public:
      typedef reference_base<ReferenceObject>  reference_base;
   typedef reference_base                   *reference_base_ptr;
private :
   reference_base_ptr ref;
public :
 reference_count(ReferenceObject* rfo):ref(new reference_base(rfo))
 {
 }
   
/*this is a  bogus copy constructor,here we add increase the reference*/
 reference_count(const reference_count& prc)
   {
    ref = prc.ref;
 ref->increase_reference();

   }
  
 reference_count& operator = (const reference_count& prc)
   {
      if(this!=&prc)
   {  ref->decrease_reference();
      ref=prc.ref;
      ref->increase_reference();
   }
  return *this;
   }
  
 ReferenceObject* getObject()
 {
  return (*ref).getObject();
 }

 ~ reference_count()
 {
  if(ref)
   ref->decrease_reference();
 }
};
#endif       //REFRENCECOUNT_HPP

 

测试:

class A
{
private:
 reference_count<int> s;
public:
 A(int * t):s(reference_count<int>(t))
{
}
   int* getObject()
   {
    return s.getObject();
   }
};

int main()
{   int * t=new int(2);
 A a(t);
 A b(a);
 int* f= new int(3);
 A c(f);
    b=c;
 cout<<"before output/n";
 cout<<*a.getObject()<<endl;
 cout<<*b.getObject()<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息