Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1408725
  • 博文数量: 120
  • 博客积分: 182
  • 博客等级: 入伍新兵
  • 技术积分: 2278
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-19 16:31
文章分类

全部博文(120)

文章存档

2015年(12)

2014年(13)

2013年(40)

2012年(55)

分类: C/C++

2013-10-17 09:30:45

        
    综述: 当两个对象要共享一份数据时,如果数据不改变,不进行数据的复制,通过浅拷贝就可以数据的共享;而当对象需要改变数据时,则做深贝。     
     程序在处理共享对象时,会使用浅拷贝和深拷贝这两种方法复制对象。
      (1)深拷贝即就是生成对象的一个完整的复制品;
      (2)浅拷贝:只是一个引用复制(比如仅仅复制指向共享数据的指针)。
这样看来,深拷贝其实是代价比较高的,要占用更多的内存和CPU资源;而浅拷贝的效率要更好些,因为它仅仅需要设置一个指向共享数据块的指针以及修改引用的计数器。
      (3)隐式共享:也叫做回写复制(copy on write)。
      隐式共享可以降低对内存和CPU资源的使用,提高程序的运行效率。使用隐式共享能使得在函数中(eg. 参数、返回值)使用值传递更有效率。  QString采用隐式共享技术,将深拷贝和浅拷贝很好地结合了起来。
举例说明饮食共享是如何工作的:

  1. QString str1 = "ubuntu";
  2. QString str2 = str1;//str2 = "ubuntu"
  3. str2[2] = "m";//str2 = "ubmntu",str1 = "ubuntu"
  4. str2[0] = "o";//str2 = "obmntu",str1 = "ubuntu"
  5. str1 = str2;//str1 = "obmntu",
line1: 初始化一个内容为"ubuntu"的字符串;
line2: 将字符串对象str1赋值给另外一个字符串str2(由QString的拷贝构造函数完成str2的初始化)。
         在对str2赋值的时候,会发生一次浅拷贝,导致两个QString对象都会指向同一个数据结构。该数据结构除了保存字符串“ubuntu”之外,还保存一个引用计数器,用来记录字符串数据的引用次数。此处,str1和str2都指向同一数据结构,所以此时引用计数器的值为2.
line3: 对str2做修改,将会导致一次深拷贝,使得对象str2指向一个新的、不同于str1所指的数据结构(该数据结构中引用计数器值为1,只有str2是指向该结构的),同时修改原来的、str1所指向的数据结构,设置它的引用计数器值为1(此时只有str1对象指向该结构);并在这个str2所指向的、新的数据结构上完成数据的修改。引用计数为1就意味着该数据没有被共享。
line4: 进一步对str2做修改,不过不会引起任何形式的拷贝,因为str2所指向的数据结构没有被共享。
line5: 将str2赋给str1.此时,str1修改它指向的数据结构的引用计数器的值位0,表示没有QString类的对象再使用这个数据结构了;因此str1指向的数据结构将会从从内存中释放掉;这一步操作的结构是QString对象str1和str2都指向了字符串为“obmntu”的数据结构,该结构的引用计数为2.
      Qt中支持引用计数的类有很多(QByteArray, QBrush, QDir, QBitmap... ...).
                 
阅读(11530) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~