句柄类
每次创建类的新对象时,初始化指针并将引用计数置为1;
当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数
(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;
调用析构函数时,析构函数减少引用计数(如果引用计数减至0,则删除基础对象)。
实现引用计数有两种经典策略:一是引入辅助类,二是使用句柄类。下面分别介绍这些内容
辅助类方法中,引用计数是size_t变量形式
句柄类中,引用计数是size_t*,并动态分配,这样多个句柄对象就指向了同一个引用计数器
http://baike.baidu.com/view/1391603.htm
// 以下为句柄类
#include "stdafx.h"
#include <iostream>
using namespace std;
template <class T>
class Handle
{
public :
T* ptr;
size_t *use; // 引用计数器使用动态分配方式定义是为了让多个句柄类对象使用同一个引用计数器
void rem_ref()
{
if(--*use == 0)
{
delete ptr;
delete use;
}
}
public:
Handle(T* p = 0):ptr(p), use(new size_t(1)){}
Handle(const Handle& h):ptr(h.ptr), use(h.use) // 多个句柄类对象使用同一个引用计数器
{
++*use;
}
T& operator *();
T* operator ->(); // 重载箭头操作符用来将本类的对象转换为类中包含的对象,从而调用那个类中的函数
// 可以参加 http://blog.sina.com.cn/s/blog_7d52efd801013txd.html
Handle& operator=(const Handle&);
~Handle()
{
rem_ref();
}
};
template <class T>
inline Handle<T>& Handle<T>::operator =(const Handle& rhs)
{
++*rhs.use;
rem_ref();
ptr = rhs.ptr;
use = rhs.use;
return *this;
}
template<class T>
inline T& Handle<T>::operator *()
{
if (ptr)
{
return *ptr;
}
else
throw runtime_error("dereference of unbound Handle");
}
template<class T>
inline T* Handle<T>::operator ->()
{
if (ptr)
{
return ptr;
}
else
throw runtime_error("access through unbound Handle");
}
int _tmain(int argc, _TCHAR* argv[])// Unicode TChar区别
{
Handle <int> hp(new int(42));
{
Handle<int> hp2 = hp;
*hp2 = 12;
cout << *hp.use << " " << *hp2.use << endl;
cout << *hp << " " << *hp2 << endl;
}
cout << *hp.use << endl;
cout << *hp << endl;
return 0;
}