《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中去,也就不用往对象上邦定任何东西。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

在64位Win7操作系统中安装Microsoft Access Engine的解决方案

现在的Win7系统中安装的一般都是32位的Office,因为微软推荐使用32位的Office,兼容性更强,稳定性更好。在使用Access作为数据库的时候,C#操作Access,如果Access是acc...

C,C++,C#三者区别

C,C++,C#三者区别 继承关系是C->C++->C# C++完全向C兼容,C程序几乎不用修改即可在C++的编译器上运行.C++也称为带类的C,在C的基础上增加了许多面向对象的概念.虽然是C的扩...

面向对象程序设计比传统的面向过程程序设计有什么好处?

http://chenlq.net/dev/cpp-why/52-object-oriented-programming-than-the-traditional-process-oriented-p...

C 和 C++ 混合编程

http://fangzhzh.info/blog/mixing-c-and-cpp-programming.html 在最近的arm开发中,因为一些特定的需求,需要使用从C文件中调用以前C...

C++ 学习基础篇(一)—— C++与C 的区别

程序的学习学无止境,只掌握一门语言是远远不够的,现在我们开始C++的学习之路,下面先看下C++ 与C 的区别 一、C++概述 1、发展历史       1980年,Bjarne Stroustrup博...

Qt:数据库编程

包含头文件 #include 在工程的.pro文件中加入 QT += sql 一、连接数据库     QSqlDatabase db = QSqlDatabase::addDatabase("...

大小端检测方法(ARM 和linux系统)

http://blog.csdn.net/haojianno1/article/details/7925797 第一部份:检测ARM或其他单片机 一、概念及详解 在各种体系的计算机中通常...

使用Subversion构建版本控制环境(Windows)

v/:* {behavior:url(#default#VML);}o/:* {behavior:url(#default#VML);}w/:* {behavior:url(#default#VML)...

Qt5.6 用SQLite数据库验证做登录框,并查删改xml文件做记住密码和自动登录<二>

写界面资源,以及控件的各种命名:  用户名编辑框命名为comboBoxUserName   ,改变样式表添加背景色白色 密码控件的命名为lineEditPassWord              ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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