QT 隐式共享 Implicit Sharing
来源:互联网 发布:知乎300txt 编辑:程序博客网 时间:2024/06/09 22:59
很多QT中的类都是隐式共享的,它在作为参数传递时既安全又有效率。
上一讲中提到了一个implicit sharing的问题,说QT容器类是隐式共享的。文档中讲了一个这样的问题:
一些Qt函数返回一个容器,如果想使用STL风格的迭代器遍历某函数的返回值,就必须复制此容器并且遍历这个副本,例如,下面的代码给出了如何遍历由QSplitter::sizes()返回的QList<int>的正确方式。
// RIGHT
const QList<int> sizes = splitter->sizes();
QList<int>::const_iterator i;
for (i = sizes.begin(); i != sizes.end(); ++i)
...
// WRONG
QList<int>::const_iterator i;
for (i = splitter->sizes().begin();
i != splitter->sizes().end(); ++i)
...
错误的原因是,每次调用QSplitter::sizes()都返回一个新的QList<int>值,如果不存储这个值,C++在开始迭代之前就会自动将其销毁,而只留下一个浮动迭代器。更糟的是,每次循环运行由于都调用了splitter->sizes().end(),QSplitter::sizes()都必须生成一个新的列表的副本。总之,如果你使用STL风格迭代器,总是要在返回值的容器副本上进行遍历。而Java Style不需要,因为它自动生成了副本。
采用隐式共享,我们复制一个容器就像复制一个指针一样快。只有复制项之一发生改变时,数据才会实际被复制,而且这一切操作都可以在后台自动处理,由于这原因,隐式共享也叫“写时复制”。
隐式共享的优点是它是一个我们必须要考虑的最优化过程,它工作不需要我们干预,同时,隐式共享也提倡由值返回的对象的整洁编程风格。
很多类都是隐式共享的,除了容器类外还有QByteArray, QBrush, QFont, QPen, QImage, QPixmap, QString, QVariant 等等。
一个共享类对象创建,它的引用计数就记为1,如果将它传递给另一个对象,那计数就加1,并两个对象都指向内存中的相同的内部数据结构。如果某一个修改了对象值就会发生深度复制,以确保他们指向的数据结构不相同。并且之前的数据计数将减1,修改后的数据计数就为1。为1表示没有被共享。
这里简单讲下深度复制和浅度复制。
当处理一个共享对象时,我们有两种拷贝一个对象的方法:也就是我们常说的深度和浅度复制。深度复制是复制一个对象,浅度是复制一个对象引用,也就是说一个指针的共享数据块。显然使用浅度复制会很快。
隐式共享对象的复制操作符(operator=)是用浅度复制实现的。
当我们要实现自己的隐式共享类时,使用QSharedData, QSharedDataPointer类。
如果对象会改变或者引用计数是比另个更大,隐式共享就会自动从共享块中分离。一个隐式共享类完全控制它内部数据,如果任何成员函数修改了它的值,隐式共享都会在修改数据前自动分离。
例如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
}
}
下面列出的类,如果一个对象被改变都会从共享数据中自动分离。编程者不需要注意这些类是共享的。因此要区别对待这些类的实例。这样,就可以作为参数传递这些实例而不关心复制代价了。
例子:
QPixmap p1, p2;
p1.load("image.bmp");
p2 = p1; // p1 and p2 share data
QPainter paint;
paint.begin(&p2); // cuts p2 loose from p1
paint.drawText(0,50, "Hi");
paint.end();
例子中p1 p2共享数据,直到为p2调用begin()。
注意:你用non-const STL风格迭代器遍历容器(隐式共享容器,例如QMap,QVector等)时不需要复制容器。正如最开始讲的那个问题。
QBitmap
QIcon
QImage
QPicture
QPixmap
QCursor
QKeySequence
QPalette
QBrush
QGradient
QPainterPath
QPen
QPolygon
QPolygonF
QRegion
QFont
QFontInfo
QFontMetrics
QFontMetricsF
QGlyphRun
QRawFont
QStaticText
QTextCursor
QTextDocumentFragment
QTextBlockFormat
QTextCharFormat
QTextFormat
QTextFrameFormat
QTextImageFormat
QTextListFormat
QTextTableCellFormat
QTextTableFormat
QNetworkCacheMetaData
QHttpPart
QNetworkCookie
QNetworkRequest
QNetworkConfiguration
QDnsDomainNameRecord
QDnsHostAddressRecord
QDnsMailExchangeRecord
QDnsServiceRecord
QDnsTextRecord
QNetworkAddressEntry
QNetworkInterface
QNetworkProxy
QNetworkProxyQuery
QSslCertificate
QSslCertificateExtension
QSslCipher
QSslConfiguration
QSslError
QSslKey
QDebug
Output stream for debugging information
QDir
Access to directory structures and their contents
QFileInfo
System-independent file information
QProcessEnvironment
Holds the environment variables that can be passed to a program
QUrl
Convenient interface for working with URLs
QUrlQuery
Way to manipulate a key-value pairs in a URL's query
QPersistentModelIndex
Used to locate data in a data model
QVariant
Acts like a union for the most common Qt data types
QMimeType
Describes types of file or data, represented by a MIME type string
QBitArray
Array of bits
QByteArray
Array of bytes
QCache
Template class that provides a cache
QContiguousCache
Template class that provides a contiguous cache
QDateTime
Date and time functions
QHash
Template class that provides a hash-table-based dictionary
QMultiHash
Convenience QHash subclass that provides multi-valued hashes
QLinkedList
Template class that provides linked lists
QList
Template class that provides lists
QLocale
Converts between numbers and their string representations in various languages
QMap
Template class that provides a red-black-tree-based dictionary
QMultiMap
Convenience QMap subclass that provides multi-valued maps
QQueue
Generic container that provides a queue
QRegExp
Pattern matching using regular expressions
QRegularExpression
Pattern matching using regular expressions
QRegularExpressionMatch
The results of a matching a QRegularExpression against a string
QRegularExpressionMatchIterator
Iterator on the results of a global match of a QRegularExpression object against a string
QSet
Template class that provides a hash-table-based set
QStack
Template class that provides a stack
QString
Unicode character string
QStringList
List of strings
QTextBoundaryFinder
Way of finding Unicode text boundaries in a string
QVector
Template class that provides a dynamic array
FROM: http://blog.csdn.net/xuguangsoft/article/details/8515613
- QT 隐式共享 Implicit Sharing
- QT的隐式共享(Implicit Sharing)
- Qt Implicit Sharing (隐式共享)
- QT 隐式共享 Implicit Sharing
- Qt框架浅析之一 ------- 隐式共享(Implicit Sharing)
- 隐式共享:qt
- Qt 隐式共享
- implicit隐式转换
- Qt隐式共享理解
- Qt中的"隐式共享"
- 伪共享false sharing
- 伪共享(False Sharing)
- 伪共享(False Sharing)
- 伪共享(False Sharing)
- 伪共享(False Sharing)
- 伪共享(False Sharing)
- 伪共享(False Sharing)
- scala implicit 隐式转换
- js 无缝轮播实现
- linux中断子系统 - softirq/tasklet
- handler的原理
- Linux命令行使用技巧
- 查找算法总结
- QT 隐式共享 Implicit Sharing
- python的import与from...import的不同之处
- 如何定义一个只能在堆上(栈上)生成对象的类?
- 【神经网络与深度学习】Caffe使用step by step:caffe框架下的基本操作和分析
- APUE_chapter3 文件IO
- 怎样阅读Android系统源码
- HHU 1017: 最小差
- OpenCV代码提取:transpose函数的实现
- 查看java内存情况命令