Qt隐式共享
看了关于Qt隐式共享的介绍,很像之前学习的智能指针,复制对象的时候引用计数+1。
(1) 深拷贝 : 即就是生成对象的一个完整的复制品;
(2)浅拷贝:只是一个引用复制(比如仅仅复制指向共享数据的指针)。
(3)隐式共享:也叫做写时复制(copy on write)。Qt中的很多C++类通过使用隐式数据共享来最大化资源的使用效率和最小化复制的资源耗费。将隐式共享类作为参数传递不仅安全而且效率高,因为在这个过程中只有指向这个数据的指针被传递,并且当且仅当有函数对这个数据进行写操作时,才会对该数据进行复制。
隐式共享可以降低对内存和CPU资源的使用,提高程序的运行效率。使用隐式共享能使得在函数中(eg. 参数、返回值)使用值传递更有效率。 QString采用隐式共享技术,将深拷贝和浅拷贝很好地结合了起来。
隐式共享大多发生的背后,编程人员一般不需要关注它们。但是,隐式共享导致Qt的容器类和STL中的容器类有很大的不同。由于隐式共享,当复制一个容器时,它们其实是共享一份数据的。
参考: Qt文档阅读笔记-隐式共享(Implicit Sharing)深入研究(理论及实例)_IT1995的博客-CSDN博客
1.上面这个博客有图可以清楚的看到隐式共享时的引用计数。
2.列出了Qt里一些隐式共享的类
参考: Qt隐式共享与显式共享_qt共享指针被保存在不同的容器中会增加引用计数吗?_求道玉的博客-CSDN博客
四、线程和隐式共享类
Qt对它的许多值类使用一种称为隐式共享的优化,尤其是QImage和QString。从Qt 4开始,隐式共享类可以安全地跨线程复制,就像任何其他值类一样。它们是完全可重入的。隐式分享确实是隐式的。
在许多人的心目中,隐式共享和多线程是不兼容的概念,因为引用计数通常是这样做的。然而,Qt使用原子引用计数来确保共享数据的完整性,避免引用计数器的潜在损坏。
注意,原子引用计数不能保证线程安全性。在线程之间共享隐式共享类的实例时,应该使用适当的锁定。这是对所有重入类(无论是否共享)的相同要求。然而,原子引用计数确实保证了一个线程在其自身、隐式共享类的本地实例上工作是安全的。 所以说可以使用信号和槽机制在不同线程之间传递数据,因为这可以在不需要显式锁定的情况下完成。
总之,Qt 4中的隐式共享类实际上是隐式共享的。即使在多线程应用程序中,也可以安全地使用。
参考: 【Qt】浅析Qt中的隐式共享_iriczhao的博客-CSDN博客