读书笔记:7章句柄第二部分

C++沉思录第七章读书笔记.[@more@]

第七章:句柄类第二部分

6章:向类中添加句柄和引用计数的技术,能通过控制引用计数就能高效的“复制“该类的对象。

缺点:必须定义一个具有类型相同的成员的新类。会困难当绑定这样的句炳到一个继承自T的(静态的)未知类的对象时。

新方法思想:将引用计数从数据中分离出来,引用计数放到它自己的对象中。

7-1回顾

class Point{

public:

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

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; }

private:

int xval, yval;

};

class UPoint {

// 所有成员都是私有的

friend class Handle;

Point p;

int u;

UPoint() :u(1) {}

UPoint(int x, int y) :p(x, y), u(1) {}

UPoint(const Point& p0) :p(p0), u(1) {}

};

class Handle {

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);

private:

//添加的

Upoint *up;

}

7-2分离引用计数

class Handle {

public:

//和前面一样

private:

Point* p;

int *u; //指向引用计数的指针

};

为什么使用Point*而不是Upoint*

Handle::Handle():u(new int(1)), p(new Point) {}

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

Handle::Handle(const Point& p0):u(new int(1)),p(new Point(p0)) {}

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

Handle& operator=(const Handle& h)

{

++*h.u;

if(--*u) ==0)

delete u;

delete p;

}

u = h.u;

p = h.p;

return *this;

}

Handle::~Handle()

{

if(--*u == 0) {

delete u;

delete p;

}

}

缺点:newdelete要成双成对的出现:一个处理引用计数,一个处理数据。问题:有没有一种方法能抽象化我们关于引用计数的工作呢?

7-3 对引用计数的抽象

为了避免日后一次次重写,尤其是假设引用技术类对句柄将要绑定的哪个对象的特性一无所知。

class UseCount {

public:

UseCount();

UseCount(const UseCount&);

UseCount& operator=(const UseCount&);

~UseCount();

//其他需要决定的内容

private:

int *p;

};

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

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

UseCount::~UseCount() if(--*p ==0) delete p; } //我感觉不对?

//重写handle

class Handle {

public:

//和前面一样

private:

Point *p;

UseCount u;

};

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) {}

class UseCount {

//和前面一样

public:

bool only();

};

bool UseCount::only() { return *p ==1; }

Handle::~Handle()

{

if(u.only())

delete p;

}

Handle 赋值操作符情况又如何?它需要类UseCount不直接支持的操作:对计数器增1,另一个减1,删除一个计数器,还要决定是否删除已赋值的数据。

为什么要私有化对UseCount对象的设置?(因为不需要这样的操作,没有用上)

class UseCount {

//和前面一样

public:

bool reattach(const UseCount&);

private:

UseCount& operator= (const UseCount& u);

};

bool UseCount::reattach(const UseCount& u)

{

++*u.p;

if(--*p==0) {

delete p;

p = u.p;

return true;

}

p =u.p;

return false;

}

Handle& Handle::operator=(const Handle& h)

{

if(u.reattach(h.u))

delete p;

p =h.p;

return *this;

}

7-4存取函数和写时复制

Point对象的单个元素的读取和写入了。我们将通过写时复制来实现值语义。要确定它的句柄是当前唯一使用该特定Poing 对象的句柄。UseCount::only帮助我们查出某个句柄是否是当前唯一使用这个句柄对象的句柄。

class UseCount {

//和前面的一样

public:

bool makeonly();

};

bool UseCount::makeonly() {

if(*p == 1)

return false;

--*p;

p = new int(1);

return true;

}

int Handle::x() const {

return p->x();

}

Handle& Handle::x(int x0) {

if(u.makeonly() )

p= new Point(*p);

p->x(x0);

return *this;

}

7-5 讨论

这个例子中功能的划分好象好奇特(看不出。道行太浅) 好几种情况下,类Handel 都请求类UseCount来做某些时,然后不厌其烦的再次要求做几乎相同的事情(看不出)。

举个例子:Handle::x存取函数使用makeonly来确保引用计数(use count)1 如果计数器被复制(因而makeonly返回true), 则复制底层的Point对象。这两项任务可以合并?(怎样合并?

我们这样做的优势:UseCount类可以在不了解其使用者任何信息的情况下与之合为一体。

UseCount类简化了一个实现中的特定子问题:它不打算为终端用户所用。不过整体上:一个相当繁杂的问题的解决方案被清晰的分割界定了。另外,最后获得的Handle类跟那些以传统方式构件起来的类一样容易使用,并且更加灵活。

(现在我由于缺乏编程经验,只能读一知半,不能举一反三,希望努力勤奋能改变这样的境况)

本章代码调试:基本没有遇到什么困难.有空在深入思考.彻底理解句柄类.

#include

class Point{

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; }

private:

int xval, yval;

};

class UseCount {

public:

UseCount();

UseCount(const UseCount&);

// UseCount& operator=(const UseCount&);

~UseCount();

int p1() {return *p;};

//其他需要决定的内容

bool only();

bool reattach(const UseCount&);

bool makeonly();

private:

UseCount& operator= (const UseCount& u);

int *p;

};

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::makeonly() {

if(*p == 1)

return false;

--*p;

p = new int(1);

return true;

}

class Handle {

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);

int num() {return u.p1();};

private:

Point *p;

UseCount u;

};

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;

}

int Handle::x() const {

return p->x();

}

Handle& Handle::x(int x0) {

if(u.makeonly() )

p= new Point(*p);

p->x(x0);

return *this;

}

int main()

{

Handle a(3, 4);

Handle b;

b=a;

Handle c=a;

Handle d=b;

// delete d;

cout<//3

cout<//3

cout<//输出为4

}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/409557/viewspace-891805/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/409557/viewspace-891805/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值