C++沉思录读书笔记(二)句柄类.上

原创 2004年07月06日 15:24:00

C++沉思录读书笔记(二)句柄类.上


延续 “C++沉思录读书笔记(一)代理类”
********
问题
********
创建代理将会复制所需要的对象,对某些类来说,复制的代价太大或者包含不能轻易被复制的资源。
如何在保持代理的多态行为的同时,避免复制对象的代价

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

********
解决方案
********
@Handle类的轮廓
定义一个适当的Handle类,将Handle类绑定到它们所控制的对象上
要求:
1. Handle类应该创建和销毁对象
  创建自己的Point对象并把它赋给一个handle
  把创建Point的参数传给Handle
2. 通过Handle类访问Point对象
  重载Handle类的operator->操作符,暴露内部的Point对象(本文未采用这种方式)
  明确选择让Handle类支持那些Point操作

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:
 //...
};

@引用计数
因为允许多个句柄绑定到单个对象上,所以要使用引用计数确定多少个句柄绑定到同一个对象上,以便确定何时删除对象
引用计数不能是句柄的一部分,否则每个句柄必须知道跟它一起被绑定到同一个对象的其他所有句柄的位置(更不能使用static成员)
引用计数不能是对象的一部分,要求不重写已存在的Point对象

class UPoint { //用来存储引用计数和Point对象
private: //纯粹为了实现而设计,所有成员私有
 friend class Handle;
 Point p;
 int u;

 UPoint(): u(1) { } //UPoint对象总是随Handle类产生,因此缺省引用计数为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; //新添加
};

@Handle类的实现
//构造函数
Handle::Handle(): up(new UPoint) { }
Handle::Handle(int x, int y): up(new UPoint(x, y)) { }
Handle::Handle(const Point& p): up(new UPoint(p)) { }

//析构函数
Handle::~Handle()
{
 if (up->u == 0)
  delete up;
}

//复制构造函数仅仅增加引用计数
Handle::Handle(const Handle& h): up(h.up) { ++up->u; }

//赋值操作符可能造成原左侧对象计数器为0
//先调用++可以保证左右两侧句柄引用同一个UPoint对象时也能工作
Handle& Handle::operator=(const Handle& h)
{
 ++h.up->u;
 if (--up->u == 0)
  delete up;
 return *this;
}

//简单的读函数
int Handle::x() const { return up->p.x(); }
int Handle::y() const { return up->p.y(); }

//复杂的写函数
/*
 句柄类在用户面前的行为
 Handle h(3,4) //原对象
 Handle h2 = h; //复制
 h2.x(5); //修改复制对象
 int n = h.x(); // 3 or 5?
*/

//指针语义:复制句柄类后,复制对象和原对象使用同一个UPoint对象

Handle& Handle::x(int x0)
{
 up->p.x(x0);
 return *this;
}

Handle& Handle::y(int y0)
{
 up->p.y(y0);
 return *this;
}

//值语义:复制句柄类后,复制对象和原对象不使用同一个UPoint对象
//在绝对必要的时候才进行对象复制,称为写时复制(copy on write),写时复制只是针对可变对象的一种优化技术

Handle& Handle::x(int x0)
{
 if (up->u != 1) {
  --up->u;
  up = new UPoint(up->p);
 }
 up->p.x(x0);
 return *this;
}

Handle& Handle::y(int y0)
{
 if (up->u != 1) {
  --up->u;
  up = new UPoint(up->p);
 }
 up->p.y(y0);
 return *this;
}

@图示
+--------+       +--------+       +--------+
| Handle |------>| UPoint |<>---->| Point  |
+--------+       +--------+       +--------+

《软件开发沉思录》读书笔记

1、  业务软件的最后一英里 l  何为最后一英里问题:简单-复杂-不堪重负-采用新系统来替换?风险?(替换的风险,不替换的风险,二难境地) l  敏捷思潮的一大贡献,是对于软件开发作为社会行为的...
  • zhang_qxian
  • zhang_qxian
  • 2017年01月04日 08:55
  • 299

读书笔记∣概率论沉思录 01

读书笔记:概率论沉思录
  • zhaozhn5
  • zhaozhn5
  • 2017年09月09日 21:09
  • 315

C++ 沉思录》阅读笔记——类的反思

类这个概念无非是数据和方法的集合,为什么我一直困惑呢?为什么不弄清楚呢? C++中的类这个概念里有4个函数比较特殊,像我这种以前有C经验的人可能一时难以适应,它们是构造函数、析构函数、复制构造函...
  • flora_yao
  • flora_yao
  • 2015年07月02日 18:02
  • 632

《C++沉思录》读书笔记之代理类

#include #include int main() { int i; for( i=0;i
  • KangRoger
  • KangRoger
  • 2014年06月11日 21:00
  • 1133

[沉思录(中英双语)·典藏本].(古罗马)奥勒留.扫描版.PDF 免费下载

下载地址:[沉思录(中英双语)·典藏本].(古罗马)奥勒留.扫描版.PDF
  • jiongyi1
  • jiongyi1
  • 2017年11月13日 21:48
  • 203

<<C++ 沉思录>> 中文人民邮电出版 勘误

> 中文人民邮电出版 勘误 这本中文版里面有各种坑爹的小错误. 比方说变量名的大小写, 同一个变量, 出现了大小写不一致, 等等问题都有. 然后今天感觉遇到了个语法问题. 关于继承权限的问题....
  • u011368821
  • u011368821
  • 2015年05月22日 15:33
  • 993

C++沉思录读书笔记(二)

句柄类举例实现 Handle.h头文件: #ifndef HANDLE_H_H #define HANDLE_H_H class Point { public: Point() : ...
  • Young0325
  • Young0325
  • 2011年08月07日 22:14
  • 659

那些年,我们读过的C、C++经典

那些年,我们捧读过的C和C++经典 导读: 从2008年开始,人民邮电出版社出版了一系列国外的C/C++经典图书,包括《C和指针》《C专家编程》《C陷阱与缺陷》《C++沉思录》等,由于图书本身的知...
  • xiaohuihui_fly1
  • xiaohuihui_fly1
  • 2012年07月09日 23:09
  • 1015

概率论沉思录 前言

    1998年4月30日Jaynes去世。此前,他曾经要我完成并出版他的这本关于概率论的书。为此,我曾纠结了一段时间。因为我认为Jaynes毫无疑问想完成这本书;但不幸的是,这本书后面的许多章节(...
  • shoreman
  • shoreman
  • 2011年04月17日 22:22
  • 2030

沉思录句柄类之二

#include using namespace std; class Point{ public: Point():xval(0),yval(0){} Point(int x,int ...
  • zhanglei0107
  • zhanglei0107
  • 2012年06月02日 16:58
  • 354
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++沉思录读书笔记(二)句柄类.上
举报原因:
原因补充:

(最多只允许输入30个字)