| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> Qt隐式共享detach函数的理解 -> 正文阅读 |
|
[C++知识库]Qt隐式共享detach函数的理解 |
隐式数据共享 以下是本人的理解: Qt 中的许多 C++ 类使用隐式数据共享来最大化资源使用并最小化复制。当作为参数传递时,因为只传递指向数据的指针,并且只有在函数写入时才复制数据(即写时复制),故隐式共享类既安全又高效, 共享类由指向共享数据块的指针组成,该指针包含引用计数和数据。 创建共享对象时,它将引用计数设置为 1。每当新对象引用共享数据时,引用计数就会增加,当对象取消引用共享数据时,引用计数会减少。当引用计数变为零时,共享数据将被删除。 在处理共享对象时,有两种复制对象的方法:深拷贝和浅拷贝。
就内存和 CPU 而言,进行深度复制可能会很昂贵。进行浅拷贝非常快,因为它只涉及设置指针和增加引用计数。 隐式共享对象的对象分配(使用 operator=())是使用浅拷贝实现的。 共享的好处是程序不需要不必要地复制数据,从而减少内存使用和数据复制。对象可以很容易地被赋值,作为函数参数发送,并从函数中返回。
此时A*的类内部的引用计数refCount 为1。当有N个A类型的指针指向A对象时,即如下图所示: 此时A*的类内部的引用计数refCount 为n,可以看到这些指针都是共享A,并没有单独复制一份A对象,即没有深度复制A对象,也就是所谓的浅拷贝。当需要对某个指针指向的A对象的属性进行更新、修改时,其它指针的调用方此时发现其所指向的A也跟着改变了(因为它们都是指向同一个A对象),这在很多情况下,不是调用方所希望的结果。比如:A是QPen对象,如下代码:
刚new出来的QPen对象被pPen1更改了,此时pPen2的调用方也跟着变化了,此时pPen2的调用方
即:
即按下图进行: pA2即为要更新的对象。先将pA2指向A对象断开,再深度复制一个A,让?pA2指向新复制出来的这个A对象。此时对新复制出来的A无论怎么修改都不会影响到原来的A对象,即非pA2的指针的调用方不会受影响。 对于QSharedDataPointer类型(QSharedDataPointer用法请参考《QPointer、QScopedPointer、QSharedDataPointer等指针用法总结》)的clone函数,当引用计数大于 1 时,clone函数由 detach() 调用以创建新副本。此函数使用运算符 new 并调用类型 T 的拷贝构造函数。QSharedDataPointer类型的的T *data() /?T?*get(),返回指向共享数据对象的指针。这两个函数也调用?detach()。QSharedDataPointer类型设计clone、data() 、 get()函数的目的就是为了对指向的对象进行更改,所以必须是深度复制才行。QSharedDataPointer类型的const T *constData() 、const?T?*data()? /?const?T?*get() 设计目的从const就可以看出仅仅是读取指向的对象,而不是进行写入更改操作,故带const的这三个函数不会调用detach,因为浅拷贝就可以完成,用浅拷贝进行读取共享对象不会导致被读取的共享对象更改,所以没必要进行资源高、效率低的深拷贝。 总结:detach发生两个必要条件是:
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 20:00:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |