为了最大化使用系统资源,更少的内存拷贝,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 |