《C++沉思录》通过句柄来避免不必要的对象的复制

原创 2006年06月14日 10:22:00

        在上一篇文章中,多次对象的复制工作,浪费了内存空间,同时也影响了程序的效率。在这里我们采用句柄的方法,消除不必要的复制。通过一个句柄来引用对象和一个引用计数器来控制该对象的创建与消除,这里所说的句柄是一个句柄类(Handle),其实就是一个指向对象的指针,当我们引用一次该对象的时候就将引用计数器加一,当计数器为零的时候,表示没有任何地方使用该对象,此时我们就要消除该对象,同时释放该对象所占用的空间。书中讲解的程序片断,整理如下:

class point     //一个point类
{
public:
 point(int x = 0, int y = 0) : xval(x), yval(y) { }
 int x(void) const { return xval; }
 int y(void) 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;    //将handle设置为该对象的友元,这样就可以使用该类的私有成员
 point p;
 int u;
 UPoint(void) : u(1) { }
 UPoint(int x, int y) : p(x, y), u(1) { }
 UPoint(const point& p0) : p(p0), u(1) { }
};
class Handle
{
public:
 Handle(void) : up(new UPoint) { }
 Handle(int x,int y) : up(new UPoint(x, y)) { }
 Handle(const point& p) : up(new UPoint(p)) {}
 Handle(const Handle* h) :up(h->up) { ++up->u; }
 Handle& operator=(const Handle& h)
 {
  ++h.up->u;
  if (--up->u == 0)
  {
   delete up;
  }
  up = h.up;
  return *this;
 }
 ~Handle(void)
 {
  if (--up->u == 0)
  {
   delete up;
  }
 }

 int x(void) const { return up->p.x(); }
 Handle& x(int x0)
 {
  if (up->u != 1)   //在句柄的复制过程中,不希望在修改原对象的值,所以就要new一个新的对象出来,对新对象进行操作,在这个地方,不知为什么不直接在handle的拷贝构造中new新的对象而要在这里new新的对象???
  {
   --up->u;
   up = new UPoint(up->p);
  }
  up->p.x(x0);
  return *this;
 }
 int y(void) const { return up->p.y(); };
 Handle& y(int y0)
 {
  if (up->u != 1)
  {
   --up->u;
   up = new UPoint(up->p);
  }
  up->p.y(y0);
  return *this;
 }
private:
 UPoint *up;
};

      在上面的程序中,的确避免的不必要的对象复制,只需要一个句柄我们就可以高效的使用这个对象。同时,在这段代码中还有一个问题:我们都要借助一个类(UPoint)来使用这个对象,将句柄邦定到该对象上,但是如果这个对象是未知的话,也就是说根本就不知道要将这个句柄邦定到那个对象上,这是我们也就无从定义UPoint。针对这一问题提出了新的解决方法,其主要思想是:将引用计数从数据中分离出来,把引用计数加到handle中去,也就不用往对象上邦定任何东西。

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

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

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

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

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

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

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

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

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

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

《C++沉思录》第五章---代理类

          在编程过程中可能要把不同的对象(这些对象可能存在一些关系:继承)放到一个容器里边,我们都知道一个基类的指针可以指向子类的一个实例,我们就在这里有用一个基类的指针使其指向不同的实例,...
  • wei801004
  • wei801004
  • 2006年06月08日 14:52
  • 1416

高效Java05:避免创建不必要的对象

就像我们大部分人所知道的,最好能重用对象,而不是每次都重复创建一个功能相同的新对象,下面举几个例子说明这个点。重用不可变对象如果对象是不可变的,那么它就始终可以被重用。对于同时提供了静态工厂方法和构造...
  • digvwell
  • digvwell
  • 2017年03月20日 23:03
  • 155

概率论沉思录 前言

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

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

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

C++沉思录读书笔记(30章)- 一个IO库的两种设计

假设需要对自定义的String类进行各种类型的IO 设计一,使用继承进行抽象,代码如下 class Write { public: virtual ~Write(); virtual vo...
  • yucan1001
  • yucan1001
  • 2011年11月11日 11:30
  • 648
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《C++沉思录》通过句柄来避免不必要的对象的复制
举报原因:
原因补充:

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