《C++沉思录》的第六章介绍了句柄类,第七章也介绍句柄类,不过这章介绍的是引用技术和对象数据分开的技术,有3个类handle,point和usecount组成(顺便添加了点自己认为重要的注释)
使用三个数据结构取代第六章的两个数据结构会增加了模块化的程度而没有增加额外的复杂性(并不是很理解这句话的意思)
class Point
{
public:
///构造函数,拷贝构造函数
Point():xval(0), yval(0){}
Point(int x, int y):xval(x), yval(y){}
Point(const Point& p):xval(p.xval), yval(p.yval){}
///设置xval和yval的值
Point& x(int xv)
{
xval = xv;
return *this;
}
Point& y(int yv)
{
yval = yv;
return *this;
}
///得到xval和yval的值
int x() const
{
return xval;
}
int y() const
{
return yval;
}
private:
int xval;
int yval;
};
相对于第六章使用Point*而不是UPoint*是很重要的,因为正是Point*使我们不仅嫩嫩狗狗将一个handle绑定到一个Point,还能将其绑定到一个继承自Point的类的对象。
这里对引用计数器进行了抽象
class UseCount
{
public:
///构造函数, 析构函数
UseCount();
~UseCount();
UseCount(const UseCount& u);
private:
UseCount& operator=(const UseCount&);
public:
bool only();
bool reattach(const UseCount& u);
///值语义还是指针语义
bool makeonly();
private:
int *p;
};
UseCount::UseCount(): p(new int(1)){}
UseCount::~UseCount()
{
if (--*p == 0)
{
delete p;
}
}
UseCount::UseCount(const UseCount& u):p(u.p)
{
++*p;
}
///UseCount& UseCount::operator=(const UseCount&)
bool UseCount::only()
{
return *p == 1;
}
bool UseCount::reattach(const UseCount& u)
{
++*u.p;
if (--*p == 0)
{
delete p;
p = u.p;
return true;
}
p = u.p;
return false;
}
bool UseCount::makeonly()
{
if (*p == 1)
{
return false;
}
--*p;
p = new int(1);
return true;
}
class Handle
{
public:
///构造函数,析构函数,拷贝构造函数和赋值操作符
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):p(h.p), u(h.u){}
~Handle();
Handle& operator=(const Handle& h);
private:
Point* p;
///引用计数器类u和数据类分离
UseCount u;
};
Handle::~Handle()
{
if (u.only())
{
delete p;
}
}
Handle& Handle::operator=(const Handle& h)
{
if (u.reattach(h.u))
{
delete p;
}
p = h.p;
return *this;
}