Qt学习:深拷贝&浅拷贝&隐式共享
来源:互联网 发布:网络歌手叶子 编辑:程序博客网 时间:2024/04/29 10:49
综述: 当两个对象要共享一份数据时,如果数据不改变,不进行数据的复制,通过浅拷贝就可以数据的共享;而当对象需要改变数据时,则做深贝。
程序在处理共享对象时,会使用浅拷贝和深拷贝这两种方法复制对象。
(1)深拷贝:即就是生成对象的一个完整的复制品;
(2)浅拷贝:只是一个引用复制(比如仅仅复制指向共享数据的指针)。
这样看来,深拷贝其实是代价比较高的,要占用更多的内存和CPU资源;而浅拷贝的效率要更好些,因为它仅仅需要设置一个指向共享数据块的指针以及修改引用的计数器。
(3)隐式共享:也叫做回写复制(copy on write)。
隐式共享可以降低对内存和CPU资源的使用,提高程序的运行效率。使用隐式共享能使得在函数中(eg. 参数、返回值)使用值传递更有效率。 QString采用隐式共享技术,将深拷贝和浅拷贝很好地结合了起来。
举例说明饮食共享是如何工作的:
- QString str1 = "ubuntu";
- QString str2 = str1;//str2 = "ubuntu"
- str2[2] = "m";//str2 = "ubmntu",str1 = "ubuntu"
- str2[0] = "o";//str2 = "obmntu",str1 = "ubuntu"
- str1 = str2;//str1 = "obmntu",
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... ...).
FROM: http://blog.chinaunix.net/uid-27177626-id-3949985.html
0 0
- Qt学习:深拷贝&浅拷贝&隐式共享
- 隐式数据共享 深拷贝 浅拷贝
- 浅拷贝,深拷贝,隐式共享的三个例子
- C++学习之拷贝构造函数(深拷贝,浅拷贝)
- 内存学习(二)深拷贝,浅拷贝,完全拷贝
- 内存学习(三)深拷贝,浅拷贝,完全拷贝
- OC学习 -- 浅拷贝和深拷贝
- iOS 学习(深拷贝 浅拷贝)
- 深拷贝&&浅拷贝
- 深拷贝||浅拷贝
- 浅拷贝,深拷贝
- 浅拷贝,深拷贝
- 深拷贝,浅拷贝
- 浅拷贝 深拷贝
- 浅拷贝.深拷贝
- 浅拷贝 深拷贝
- 深拷贝,浅拷贝
- 深拷贝、浅拷贝
- Excel文件导入Mysql
- Android HTTP 请求超过超时时间未返回 报错java.net.UnknownHostException: Unable to resolve host
- 会分期
- iOS 应用下载和评分地址
- 嵌入式Linux串口操作接口
- Qt学习:深拷贝&浅拷贝&隐式共享
- 埃拉托色尼晒算法(C实现)
- [UVA 11427] Expect the Expected
- C++编程中内存溢出问题
- UVALive 3971-Assemble- 最小值最大化(二分)
- 关于Maven中打包命令(项目中打补丁的时候用到)
- Redis手册(String数据类型)
- shell导出和导入redis
- C语言的变量存储类型