为了最大化使用系统资源,更少的内存拷贝,QT中的很多类使用了隐式数据共享。当传递参数时,使用隐式共享类既安全又高效,因为只传递对象指针。当对象中的数据被修改时,对象才会被拷贝。也就是我们常说的“写拷贝”(copy-on-write)。
概述:
共享类由一个指向共享数据块的指针,此共享数据块包含对象的引用计数和对象的数据。
当一个共享对象被创建时,它的引用计数设置为1。当一个新的对象引用了此对象,那么引用计数就会加1。反之,如果一个对象不再引用此对象,引用计数就会减1。而引用计数为0时,共享对象会被删除。
有两种方法拷贝共享对象,我们通常叫做深拷贝和浅拷贝。深拷贝会复制对象,而浅拷贝是引用拷贝,只复制共享数据块的指针。深拷贝会占用较多内存和CPU资源,因为它仅仅设置指针的值,增加引用计数。
隐式数据对象赋值(操作符=())操作使用浅拷贝。
共享的优点,在不必要的情况下,程序不需要复制数据,从而减少内存使用和数据拷贝。对象能被简单的赋值,作为函数参数传递,并从函数返回。
隐式数据的特性对于用户是透明的。程序员不需要去担心这些特性。甚至在多线的应用中,隐式共享的具体细节,在“ Threads and Implicitly Shared Classes”中有详细解释。
如果想自定义隐式共享类,可以使用QSharedData和QSharedDataPointer。
隐式共享的具体细节:
如果对象即将改变,并且引用计数大于1,隐式共享对象会自动从共享数据块中分离。(通常叫做写复制或值语义。)
隐式共享类对内部数据操作敏感。任何成员函数修改了共享数据,在修改数据之前都会分离共享数据块。
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共享数据,直到QPainter::begin对p2调用,因为绘制操作会修改共享对象。
警告:当你使用非常量的标准模板库风格迭代器迭代隐式共享容器(QMap、QVector等等)时,不要拷贝这些容器。
QBitmap |
The QBitmap class provides monochrome (1-bit depth) pixmaps. |
QIcon |
The QIcon class provides scalable icons in different modes and states. |
QImage |
The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device. |
QPicture |
The QPicture class is a paint device that records and replays QPainter commands. |
QPixmap |
The QPixmap class is an off-screen image representation that can be used as a paint device. |
QCursor |
The QCursor class provides a mouse cursor with an arbitrary shape. |
QKeySequence |
The QKeySequence class encapsulates a key sequence as used by shortcuts. |
QPalette |
The QPalette class contains color groups for each widget state. |
QOpenGLDebugMessage |
The QOpenGLDebugMessage class wraps an OpenGL debug message. |
QBrush |
The QBrush class defines the fill pattern of shapes drawn by QPainter. |
QGradient |
The QGradient class is used in combination with QBrush to specify gradient fills. |
QPainterPath |
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be constructed and reused. |
QPen |
The QPen class defines how a QPainter should draw lines and outlines of shapes. |
QPolygon |
The QPolygon class provides a vector of points using integer precision. |
QPolygonF |
The QPolygonF class provides a vector of points using floating point precision. |
QRegion |
The QRegion class specifies a clip region for a painter. |
QFont |
The QFont class specifies a font used for drawing text. |
QFontInfo |
The QFontInfo class provides general information about fonts. |
QFontMetrics |
The QFontMetrics class provides font metrics information. |
QFontMetricsF |
The QFontMetricsF class provides font metrics information. |
QGlyphRun |
The QGlyphRun class provides direct access to the internal glyphs in a font. |
QRawFont |
The QRawFont class provides access to a single physical instance of a font. |
QStaticText |
The QStaticText class enables optimized drawing of text when the text and its layout is updated rarely. |
QTextCursor |
The QTextCursor class offers an API to access and modify QTextDocuments. |
QTextDocumentFragment |
The QTextDocumentFragment class represents a piece of formatted text from a QTextDocument. |
QTextBlockFormat |
The QTextBlockFormat class provides formatting information for blocks of text in a QTextDocument. |
QTextCharFormat |
The QTextCharFormat class provides formatting information for characters in a QTextDocument. |
QTextFormat |
The QTextFormat class provides formatting information for a QTextDocument. |
QTextFrameFormat |
The QTextFrameFormat class provides formatting information for frames in a QTextDocument. |
QTextImageFormat |
The QTextImageFormat class provides formatting information for images in a QTextDocument. |
QTextListFormat |
The QTextListFormat class provides formatting information for lists in a QTextDocument. |
QTextTableCellFormat |
The QTextTableCellFormat class provides formatting information for table cells in a QTextDocument. |
QTextTableFormat |
The QTextTableFormat class provides formatting information for tables in a QTextDocument. |
QNetworkCacheMetaData |
The QNetworkCacheMetaData class provides cache information. |
QHttpPart |
The QHttpPart class holds a body part to be used inside a HTTP multipart MIME message. |
QNetworkCookie |
The QNetworkCookie class holds one network cookie. |
QNetworkRequest |
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager. |
QNetworkConfiguration |
The QNetworkConfiguration class provides an abstraction of one or more access point configurations. |
QDnsDomainNameRecord |
The QDnsDomainNameRecord class stores information about a domain name record. |
QDnsHostAddressRecord |
The QDnsHostAddressRecord class stores information about a host address record. |
QDnsMailExchangeRecord |
The QDnsMailExchangeRecord class stores information about a DNS MX record. |
QDnsServiceRecord |
The QDnsServiceRecord class stores information about a DNS SRV record. |
QDnsTextRecord |
The QDnsTextRecord class stores information about a DNS TXT record. |
QNetworkAddressEntry |
The QNetworkAddressEntry class stores one IP address supported by a network interface, along with its associated netmask and broadcast address. |
QNetworkInterface |
The QNetworkInterface class provides a listing of the host's IP addresses and network interfaces. |
QNetworkProxy |
The QNetworkProxy class provides a network layer proxy. |
QNetworkProxyQuery |
The QNetworkProxyQuery class is used to query the proxy settings for a socket. |
QSslCertificate |
The QSslCertificate class provides a convenient API for an X509 certificate. |
QSslCertificateExtension |
The QSslCertificateExtension class provides an API for accessing the extensions of an X509 certificate. |
QSslCipher |
The QSslCipher class represents an SSL cryptographic cipher. |
QSslConfiguration |
The QSslConfiguration class holds the configuration and state of an SSL connection |
QSslError |
The QSslError class provides an SSL error. |
QSslKey |
The QSslKey class provides an interface for private and public keys. |
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 |