Qt学习笔记1.3.3QtCore-隐式共享


隐式共享
Qt中的许多c++类使用隐式数据共享来最大化资源使用并最小化复制。隐式共享类作为参数传递时既安全又高效,因为只传递指向数据的指针,并且只有当函数写入数据时才会复制数据,即写时复制(copy-on-write)。

概述

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

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

在处理共享对象时,有两种复制对象的方法。我们通常讲深(deep)拷贝和浅(shallow)拷贝。深度拷贝意味着复制一个对象。浅拷贝是一种引用拷贝,即只是一个指向共享数据块的指针。就内存和CPU而言,进行深度复制可能代价高昂。创建浅拷贝非常快,因为它只需要设置一个指针并增加引用计数

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

共享的好处是程序不需要不必要地复制数据,从而减少内存使用和数据复制。对象可以很容易地分配,作为函数参数发送,并从函数返回

隐性分享大多发生在幕后;程序员很少需要担心这个问题。然而,Qt的容器迭代器与STL中的容器迭代器具有不同的行为Qt学习笔记1.3.1 Qt Core-容器类

在多线程应用程序中,隐式共享发生Qt学习笔记1.2.5 Qt Core线程与并发编程之Qt模块中的线程支持

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

隐式共享细节

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

隐式共享类控制其内部数据。在任何修改其数据的成员函数中,它在修改数据之前自动分离。但是,请注意容器迭代器的特殊情况Qt学习笔记1.3.1 Qt Core-容器类

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

void QPen::setStyle(Qt::PenStyle style)
{
    detach();           // 与公共数据分离
    d->style = 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);               // p2从p1中分离
paint.drawText(0,50, "Hi");
paint.end();

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

其他隐式共享数据类见原文https://doc.qt.io/archives/qt-5.12/implicit-sharing.html

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值