C++沉思录读书笔记(7章)-句柄:第二部分(一)

2014-11-24 12:36:26 · 作者: · 浏览: 2

上一回讨论的句柄技术有一个明显的缺点:为了将句柄捆绑到类T的对象上,必须要新定义一个具有类型为T的成员对象的新类。

这个毛病相当麻烦,如果想新设计一个类的句柄类,就需要新定义两个类。

C++之父提到过一种定义句柄类的技术可以弥补这一个缺点,主要思想就是将引用技术从数据中分离出来,把引用计数放到句柄类自己的对象之中。

示例代码如下所示:

#include

using namespace std;

//-----------------------------------------

class Point

{

private:

int xval,yval;

public:

Point():xval(0),yval(0){}

Point(int x,int y):xval(x),yval(y){}

int x()const{return xval;}

int y()const{return yval;}

Point& x(int xv){xval=xv;return *this;}

Point& y(int yv){yval=yv;return *this;}

};

//------------------------------------------------------

class UseCount

{

private:

int* p;

public:

UseCount();

UseCount(const UseCount&);

UseCount& operator=(const UseCount&);

~UseCount();

bool only();

bool reattach(const UseCount&);

bool make_only();

};

UseCount::UseCount():p(new int(1)){}

UseCount::UseCount(const UseCount&u):p(u.p){++*p;}

UseCount::~UseCount()

{

if (--*p==0)

{

delete p;

}

}

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::make_only()

{

if (*p==1)

return false;

--*p;

p=new int(1);

return true;

}

//-------------------------------------------

class Handle

{

private:

Point* p;

UseCount u;

public:

Handle();

Handle(int,int);

Handle(const Point&);

Handle(const Handle&);

Handle& operator =(const Handle&);

~Handle();

int x()const;

Handle&x(int);

int y()const;

Handle&y(int);

};

Handle::Handle():p(new Point){}

Handle::Handle(int x,int y):p(new Point(x,y)){}

Handle::Handle(const Point&p0):p(new Point(p0)){}

Handle::Handle(const Handle&h):u(h.u),p(h.p){}

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;

/* //自定义版本不使用reattach辅助方法,自认为更容易理解,但很丑陋

(*(h.u.p))++;

if(*(u.p) == 1)

{

delete p;

delete u.p;

}

else

(*(u.p))--;

u.p = h.u.p;

p = h.p;

return *this;

*/

}

int Handle::x()const

{

return p->x();

}

int Handle::y()const

{

return p->y();

}

Handle& Handle::x(int x0)

{

if (u.make_only())

p=new Point(*p);

p->x(x0);

return *this;

/* //自定义版本,不使用辅助方法make_only,自认为更容易理解,但很丑陋

if(*(u.p) == 1)

p->x(x0);

else

{

(*(u.p))--;

u.p = new int(1);

p = new Point(*p);

p->x(x0);

}

retrun *this;

*/

}

Handle& Handle::y(int y0)

{

if (u.make_only())

p=new Point(*p);

p->y(y0);

return *this;

/* //自定义版本,不使用辅助方法make_only,自认为更容易理解,但很丑陋

if(*(u.p) == 1)

p->y(x0);

else

{

(*(u.p))--;

u.p = new int(1);

p = new Point(*p);

p->y(x0);

}

retrun *this;

*/

}

//---------------------------------------------------

int main()

{

Handle h(3,4);

Handle h2 = h;

h2.x(5);

i