爲了最大化使用系統資源,更少的內存拷貝,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等等)時,不要拷貝這些容器。
The QBitmap class provides monochrome (1-bit depth) pixmaps. |
|
The QIcon class provides scalable icons in different modes and states. |
|
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. |
|
The QPicture class is a paint device that records and replays QPainter commands. |
|
The QPixmap class is an off-screen image representation that can be used as a paint device. |
|
The QCursor class provides a mouse cursor with an arbitrary shape. |
|
The QKeySequence class encapsulates a key sequence as used by shortcuts. |
|
The QPalette class contains color groups for each widget state. |
|
The QOpenGLDebugMessage class wraps an OpenGL debug message. |
|
The QBrush class defines the fill pattern of shapes drawn by QPainter. |
|
The QGradient class is used in combination with QBrush to specify gradient fills. |
|
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be constructed and reused. |
|
The QPen class defines how a QPainter should draw lines and outlines of shapes. |
|
The QPolygon class provides a vector of points using integer precision. |
|
The QPolygonF class provides a vector of points using floating point precision. |
|
The QRegion class specifies a clip region for a painter. |
|
The QFont class specifies a font used for drawing text. |
|
The QFontInfo class provides general information about fonts. |
|
The QFontMetrics class provides font metrics information. |
|
The QFontMetricsF class provides font metrics information. |
|
The QGlyphRun class provides direct access to the internal glyphs in a font. |
|
The QRawFont class provides access to a single physical instance of a font. |
|
The QStaticText class enables optimized drawing of text when the text and its layout is updated rarely. |
|
The QTextCursor class offers an API to access and modify QTextDocuments. |
|
The QTextDocumentFragment class represents a piece of formatted text from a QTextDocument. |
|
The QTextBlockFormat class provides formatting information for blocks of text in a QTextDocument. |
|
The QTextCharFormat class provides formatting information for characters in a QTextDocument. |
|
The QTextFormat class provides formatting information for a QTextDocument. |
|
The QTextFrameFormat class provides formatting information for frames in a QTextDocument. |
|
The QTextImageFormat class provides formatting information for images in a QTextDocument. |
|
The QTextListFormat class provides formatting information for lists in a QTextDocument. |
|
The QTextTableCellFormat class provides formatting information for table cells in a QTextDocument. |
|
The QTextTableFormat class provides formatting information for tables in a QTextDocument. |
|
The QNetworkCacheMetaData class provides cache information. |
|
The QHttpPart class holds a body part to be used inside a HTTP multipart MIME message. |
|
The QNetworkCookie class holds one network cookie. |
|
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager. |
|
The QNetworkConfiguration class provides an abstraction of one or more access point configurations. |
|
The QDnsDomainNameRecord class stores information about a domain name record. |
|
The QDnsHostAddressRecord class stores information about a host address record. |
|
The QDnsMailExchangeRecord class stores information about a DNS MX record. |
|
The QDnsServiceRecord class stores information about a DNS SRV record. |
|
The QDnsTextRecord class stores information about a DNS TXT record. |
|
The QNetworkAddressEntry class stores one IP address supported by a network interface, along with its associated netmask and broadcast address. |
|
The QNetworkInterface class provides a listing of the host's IP addresses and network interfaces. |
|
The QNetworkProxy class provides a network layer proxy. |
|
The QNetworkProxyQuery class is used to query the proxy settings for a socket. |
|
The QSslCertificate class provides a convenient API for an X509 certificate. |
|
The QSslCertificateExtension class provides an API for accessing the extensions of an X509 certificate. |
|
The QSslCipher class represents an SSL cryptographic cipher. |
|
The QSslConfiguration class holds the configuration and state of an SSL connection |
|
The QSslError class provides an SSL error. |
|
The QSslKey class provides an interface for private and public keys. |
|
Output stream for debugging information |
|
Access to directory structures and their contents |
|
System-independent file information |
|
Holds the environment variables that can be passed to a program |
|
Convenient interface for working with URLs |
|
Way to manipulate a key-value pairs in a URL's query |
|
Used to locate data in a data model |
|
Acts like a union for the most common Qt data types |
|
Describes types of file or data, represented by a MIME type string |
|
Array of bits |
|
Array of bytes |
|
Template class that provides a cache |
|
Template class that provides a contiguous cache |
|
Date and time functions |
|
Template class that provides a hash-table-based dictionary |
|
Convenience QHash subclass that provides multi-valued hashes |
|
Template class that provides linked lists |
|
Template class that provides lists |
|
Converts between numbers and their string representations in various languages |
|
Template class that provides a red-black-tree-based dictionary |
|
Convenience QMap subclass that provides multi-valued maps |
|
Generic container that provides a queue |
|
Pattern matching using regular expressions |
|
Pattern matching using regular expressions |
|
The results of a matching a QRegularExpression against a string |
|
Iterator on the results of a global match of a QRegularExpression object against a string |
|
Template class that provides a hash-table-based set |
|
Template class that provides a stack |
|
Unicode character string |
|
List of strings |
|
Way of finding Unicode text boundaries in a string |
|
Template class that provides a dynamic array |