Qt扫盲--隐式共享基本原理

隐式共享基本原理

一、快速了解

Qt中的许多C++类使用 隐式数据共享 来实现资源最大化使用和最小化复制代价。隐式共享类在作为参数传递时既安全又高效,因为只传递指向数据的指针,并且仅当函数写入数据时(即写时复制)才会复制数据。

这篇文章主要是说,隐式共享的大概意思。
关于容器、线程中的隐式共享,以及自定义实现隐式共享,大概不谈及。

隐式数据共享是在我们底层一些的,但是我们还是应该将它们的单独实例视为单独的对象。 它们将始终作为单独的对象,但具有尽可能共享数据的额外好处。因此,我们还是可以通过值将这些类的实例作为参数传递给函数,而不用担心复制开销。

QPixmap p1, p2;
p1.load("image.bmp");
p2 = p1;                        // p1 and p2 共享相同资源

QPainter paint;
paint.begin(&p2);               // 用的p2的值,其实在底层用的是p1对象的值
paint.drawText(0,50, "Hi");
paint.end();

p2.caled(200, 200);				//p2发生修改时拷贝,此时的 p1 p2底层是两个对象

二、详细情况

一个共享类含有指向共享数据块的指针组成;数据块里有两个部分【重点关注的是数据块里的东西】

  • 引用计数
  • 共享数据

计数器的功能:创建共享对象时,它会将引用计数设置为1。每当新对象引用共享数据时,引用计数就会增加,而当对象取消引用共享数据时,引用计数就会减少。当引用计数变为零时,共享数据将被删除。

在传递函数参数、或者处理共享对象时,有两种复制对象的方法。我们通常谈论深浅拷贝。深拷贝意味着复制一个对象。浅拷贝是一个参考副本,即在只读操作时只是传递一个指向共享数据块的指针。就内存和CPU而言,深拷贝可能代价较大。但浅拷贝非常快,因为它只需要设置指针和增加引用计数就行。

  • 隐式共享对象的对象分配(运算符=())是使用浅拷贝实现的。

共享的好处: 在程序中不需要进行不必要的复制数据,从而减少内存使用和数据复制操作运算。对象可以很容易地分配、作为函数参数发送和从函数返回。隐性分享大多发生在幕后;我们其实很少需要担心它。

更改对象值时共享的内部机制: 如果对象即将更改并且引用计数大于1时,隐式共享会自动将对象从共享块中分离。这通常被称为写时复制。隐式共享的类可以控制它的内部数据。在任何修改其数据的成员函数中,它会在修改数据之前自动分离。

就像Qt中的QPen类使用隐式共享 部分代码。

void QPen::setStyle(Qt::PenStyle style)
  {
      detach();           // detach from common data
      d->style = style;   // set the style member
  }

  void QPen::detach()
  {
      if (d->ref != 1) {
          ...             // perform a deep copy
      }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳风暴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值