引用计数是为了节省空间的目的,在一个类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;
}