第六章谈及一种向类中添加句柄和引用计数的技术,以能够通过值控制引用计数就能够高效地“复制”该类的对象。这种技术有一个明显的缺点:为了把句柄绑定到类T的对象上,必须定义一个具有类型T的成员的新类。
分离引用计数:
class Handle
{
public:
Handle(): u(new int(1)), p(new Point) {}
Handle(int x, int y): u(new int(1)), p(new Point(x, y)) {}
Handle(const Point& p0): u(new int(1)), p(new Point(p0)) {}
Handle(const Handle& h): u(h.u), p(h.p) {++*u;}
Handle& operator=(const Handle& h)
{
++*h.u;
if (--*u == 0)
{
delete u;
u = NULL;
delete p;
p = NULL;
}
u = h.u;
p = h.p;
return *this;
}
~Handle()
{
if (--*u == 0)
{
delete u;
u = NULL;
delete p;
p = NULL;
}
}
private:
Point* p;
int* u; //指向引用计数的指针
};
对引用计数的抽象:
class UseCount
{
public:
UseCount():count(new int(1)){}
UseCount(const UseCount& uc):count(uc.count){ ++*count;}
UseCount& operator=(const UseCount &u)
{
reattach(u);
return *this;
}
~UseCount()
{
if (--*count == 0)
{
delete count;
count == NULL;
}
}
bool only() { return *count == 1;} //判断是否只指向一个计数,用于判断是否要删除
bool reattach(const UseCount &u) //重新连接,用于复制
{
++*u.count;
if (--*u.count == 0)
{
delete count;
count = u.count;
return true;
}
count = u.count;
return false;
}
bool makeonly() //分配一个新的,用于写时复制技术
{
if (*count == 1)
return false;
--*count;
count = new int(1);
return true;
}
private:
int *count;//计数
};
class Handle
{
public:
//由于构造函数可以缺省UsrCount构造函数的行为,所以变得简单了
Handle(): p(new Point) {}
Handle(int x, int y): p(new Point(x, y)) {}
Handle(const Point& p0): p(new Point(p0)) {}
Handle(const Handle& h): u(h.u), p(h.p) {}
Handle& operator=(const Handle& h)
{
if (u.reattach(h.u))
{
delete p;
}
p = h.p;
return *this;
}
~Handle()
{
if (u->only())
{
delete p;
p = NULL;
}
}
int x() const {return p->x();}
Handle& x(int x0)
{
if (y.makeonly())
{
p = new Point(*p);
}
p->x(x0);
return *this;
}
private:
Point* p;
UseCount* u; //指向引用计数的指针
};