【QT】隐式共享

QT隐式共享

Qt 中许多 C++ 类使用隐式数据共享来最大程度地利用资源并最小化复制。隐式共享类在作为参数传递时既安全又高效,因为只传递数据的指针,只有在函数写入数据时才会复制数据,即写时复制

概述

共享类由指向包含引用计数和数据的共享数据块的指针组成。

创建共享对象时,将引用计数设置为 1。每当新对象引用共享数据时,引用计数增加,当对象取消引用共享数据时,引用计数减少。当引用计数变为零时,共享数据被删除。

处理共享对象时,有两种复制对象的方式。通常我们谈论深复制浅复制。深复制意味着复制对象。浅复制是一个引用复制,即只是一个指向共享数据块的指针。进行深复制可能会导致内存和 CPU 方面的昂贵。进行浅复制非常快,因为它只涉及设置指针和增加引用计数。

隐式共享对象的对象赋值(使用 operator=())是使用浅复制实现的。

共享的好处在于程序不需要不必要地复制数据,这导致内存使用较低且数据复制较少。对象可以轻松分配、作为函数参数传递和从函数返回。

隐式共享大多数时候都在幕后进行,程序员很少需要担心它。但是,Qt 的容器迭代器与 STL 的容器迭代器有不同的行为。请阅读 隐式共享迭代器问题。

在多线程应用程序中,隐式共享会发生,详细信息请参阅 线程和隐式共享类。

当您实现自己的隐式共享类时,请使用 QSharedData 和 QSharedDataPointer 类。

隐式共享详解

如果对象即将更改且引用计数大于一,则隐式共享会自动将对象与共享块分离。(这通常称为写时复制值语义。)

隐式共享类控制其内部数据。在任何修改数据的成员函数中,在修改数据之前,它会自动分离数据。但请注意,容器迭代器有一个特殊情况;请参阅 隐式共享迭代器问题。

使用隐式共享的 QPen 类在所有更改内部数据的成员函数中都会从共享数据中分离出来。

代码片段:

void QPen::setStyle(Qt::PenStyle style)
{
    detach();           // 从公共数据中分离
    d->style = style;   // 设置样式成员
}

void QPen::detach()
{
    if (d->ref != 1) {
        ...             // 执行深度复制
    }
}

类列表

如果对象即将更改,则下面列出的类会自动从公共数据中分离。程序员甚至不会注意到对象是共享的。因此,您应该将它们的不同实例视为单独的对象。它们始终会被视为单独的对象,但是具有在可能的情况下共享数据的额外好处。因此,您可以将这些类的实例作为值传递给函数的参数,而不必担心复制开销。

示例:

QPixmap p1, p2;
p1.load("image.bmp");
p2 = p1;                        // p1 和 p2 共享数据

QPainter paint;
paint.begin(&p2);               // 从 p1 中分离 p2
paint.drawText(0,50, "Hi");
paint.end();

在此示例中,和会共享数据,直到调用 QPainter::begin() 为止,因为绘制像素图会修改它。p1、p2 和 p2

警告: 在使用 STL 风格迭代器 时,复制隐式共享容器(QMap、QVector 等)时要小心。请参阅 隐式共享迭代器问题。

英文中文
QBitArray位数组
QBitmap单色(1 位深度)位图
QBrushQPainter 绘制的形状的填充模式定义
QByteArray字节数组
QByteArrayList字节数组列表
QCache提供缓存的模板类
QCollator根据本地化的排序算法比较字符串
QCollatorSortKey用于加速字符串排序的对象
QCommandLineOption定义可能的命令行选项
QContiguousCache提供连续缓存的模板类
QCursor具有任意形状的鼠标光标
QDBusPendingCall指代一个挂起的异步调用
QDBusUnixFileDescriptor持有一个 Unix 文件描述符
QDateTime日期和时间函数
QDebug用于调试信息的输出流
QDir访问目录结构及其内容
QDnsDomainNameRecord存储域名记录的信息
QDnsHostAddressRecord存储主机地址记录的信息
QDnsMailExchangeRecord存储 DNS MX 记录的信息
QDnsServiceRecord存储 DNS SRV 记录的信息
QDnsTextRecord存储 DNS TXT 记录的信息
QFileInfo系统独立的文件信息
QFont指定用于绘制文本的字体查询
QFontInfo字体的一般信息
QFontMetrics字体度量信息
QFontMetricsF字体度量信息
QGlyphRun直接访问字体中的内部字形
QGradient与 QBrush 结合使用以指定渐变填充
QHash提供基于哈希表的字典的模板类
QHostAddressIP 地址
QHttp2Configuration控制 HTTP/2 的参数和设置
QHttpPart保存在 HTTP 多部分 MIME 消息中的部分
QIcon不同模式和状态下的可缩放图标
QImage硬件独立的图像表示,允许直接访问像素数据,并可用作绘图设备
QJsonArray封装了 JSON 数组
QJsonDocument读取和写入 JSON 文档的方式
QJsonObject封装了 JSON 对象
QJsonParseError在 JSON 解析过程中报告错误
QJsonValue封装了 JSON 中的值
QKeySequence封装了快捷键中使用的键序列
QList提供列表的模板类
QLocale在各种语言之间转换数字及其字符串表示
QMap提供基于红黑树的字典的模板类
QMimeType描述文件或数据类型的 MIME 类型字符串
QMultiHash提供多值哈希的便利 QHash 子类
QMultiMap提供多值映射的便利 QMap 子类
QNetworkAddressEntry存储由网络接口支持的一个 IP 地址,以及其关联的子网掩码和广播地址
QNetworkCacheMetaData缓存信息
QNetworkCookie包含一个网络 cookie
QNetworkInterface主机的 IP 地址和网络接口列表
QNetworkProxy网络层代理
QNetworkProxyQuery用于查询套接字的代理设置
QNetworkRequest保存要与 QNetworkAccessManager 发送的请求
QOpenGLDebugMessage封装了 OpenGL 调试消息
QPainterPath绘图操作的容器,使得可以构造和重用图形形状
QPalette包含每个小部件状态的颜色组
QPen定义 QPainter 如何绘制线条和形状的轮廓
QPersistentModelIndex用于定位数据模型中的数据
QPicture记录和重播 QPainter 命令的绘图设备
QPixmap可用作绘图设备的屏幕外图像表示
QPolygon使用整数精度的点的向量
QPolygonF使用浮点精度的点的向量
QProcessEnvironment保存可以传递给程序的环境变量
QQueue提供队列的通用容器
QRawFont访问字体的单个物理实例
QRegExp使用正则表达式进行模式匹配
QRegion为 QPainter 指定剪辑区域
QRegularExpression使用正则表达式进行模式匹配
QRegularExpressionMatch对 QRegularExpression 与字符串进行匹配的结果
QRegularExpressionMatchIterator针对 QRegularExpression 对象与字符串的全局匹配结果的迭代器
QSet提供基于哈希表的集合的模板类
QSslCertificateX509 证书的方便 API
QSslCertificateExtension访问 X509 证书的扩展的 API
QSslCipher表示 SSL 加密密码
QSslConfiguration保存 SSL 连接的配置和状态
QSslDiffieHellmanParameters服务器的 Diffie-Hellman 参数的接口
QSslErrorSSL 错误
QSslKey私钥和公钥的接口
QSslPreSharedKeyAuthenticator预共享密钥(PSK)密码套件的身份验证数据
QStack提供堆栈的模板类
QStaticText当文本及其布局不经常更新时,启用文本的优化绘制
QStorageInfo提供关于当前挂载的存储和驱动器的信息
QStringUnicode 字符串
QStringList字符串列表
QTextBlockFormatQTextDocument 中文本块的格式信息
QTextBoundaryFinder在字符串中查找 Unicode 文本边界
QTextCharFormatQTextDocument 中字符的格式信息
QTextCursor提供访问和修改 QTextDocuments 的 API
QTextDocumentFragment表示来自 QTextDocument 的格式化文本片段
QTextFormatQTextDocument 的格式信息
QTextFrameFormatQTextDocument 中框架的格式信息
QTextImageFormatQTextDocument 中图像的格式信息
QTextListFormatQTextDocument 中列表的格式信息
QTextTableCellFormatQTextDocument 中表格单元格的格式信息
QTextTableFormatQTextDocument 中表格的格式信息
QUrl用于处理 URL 的便捷接口
QUrlQuery在 URL 的查询中操作键值对的方式
QVariant对最常见的 Qt 数据类型起到联合作用
QVector提供动态数组的模板类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值