Warning
This section contains snippets that were automatically translated from C++ to Python and may contain errors.
Implicit Sharing#
Many C++ classes in Qt use implicit data sharing to maximize resource usage and minimize copying. Implicitly shared classes are both safe and efficient when passed as arguments, because only a pointer to the data is passed around, and the data is copied only if and when a function writes to it, i.e., copy-on-write.
Overview#
A shared class consists of a pointer to a shared data block that contains a reference count and the data.
When a shared object is created, it sets the reference count to 1. The reference count is incremented whenever a new object references the shared data, and decremented when the object dereferences the shared data. The shared data is deleted when the reference count becomes zero.
When dealing with shared objects, there are two ways of copying an object. We usually speak about deep and shallow copies. A deep copy implies duplicating an object. A shallow copy is a reference copy, i.e. just a pointer to a shared data block. Making a deep copy can be expensive in terms of memory and CPU. Making a shallow copy is very fast, because it only involves setting a pointer and incrementing the reference count.
Object assignment (with operator=()) for implicitly shared objects is implemented using shallow copies.
The benefit of sharing is that a program does not need to duplicate data unnecessarily, which results in lower memory use and less copying of data. Objects can easily be assigned, sent as function arguments, and returned from functions.
Implicit sharing mostly takes place behind the scenes; the programmer rarely needs to worry about it. However, Qt’s container iterators have different behavior than those from the STL. Read Implicit sharing iterator problem .
In multithreaded applications, implicit sharing takes place, as explained in Threads and Implicitly Shared Classes.
When implementing your own implicitly shared classes, use the QSharedData
and QSharedDataPointer
classes.
Implicit Sharing in Detail#
Implicit sharing automatically detaches the object from a shared block if the object is about to change and the reference count is greater than one. (This is often called copy-on-write or value semantics.)
An implicitly shared class has control of its internal data. In any member functions that modify its data, it automatically detaches before modifying the data. Notice, however, the special case with container iterators; see Implicit sharing iterator problem .
The QPen class, which uses implicit sharing, detaches from the shared data in all member functions that change the internal data.
Code fragment:
def setStyle(self, style): detach() # detach from common data d.style = style # set the style member def detach(self): if d.ref != 1: ... // perform a deep copy
List of Classes#
The classes listed below automatically detach from common data if an object is about to be changed. The programmer will not even notice that the objects are shared. Thus you should treat separate instances of them as separate objects. They will always behave as separate objects but with the added benefit of sharing data whenever possible. For this reason, you can pass instances of these classes as arguments to functions by value without concern for the copying overhead.
Example:
p1, = QPixmap() p1.load("image.bmp") p2 = p1 # p1 and p2 share data paint = QPainter() paint.begin(p2) # cuts p2 loose from p1 paint.drawText(0,50, "Hi") paint.end()
In this example, p1
and p2
share data until QPainter::begin() is called for p2
, because painting a pixmap will modify it.
Warning
Be careful with copying an implicitly shared container ( QMap
, QList
, etc.) while you use STL-style iterator . See Implicit sharing iterator problem .
|
The QDebug class provides an output stream for debugging information. |
The QDir class provides access to directory structures and their contents. |
|
The QFileInfo class provides an OS-independent API to retrieve information about file system entries. |
|
The QProcessEnvironment class holds the environment variables that can be passed to a program. |
|
Provides information about currently mounted storage and drives. |
|
The QUrl class provides a convenient interface for working with URLs. |
|
The QUrlQuery class provides a way to manipulate a key-value pairs in a URL’s query. |
|
The QPersistentModelIndex class is used to locate data in a data model. |
|
|
The QVariant class acts like a union for the most common Qt data types. |
The QMimeType class describes types of file or data, represented by a MIME type string. |
|
The QJsonArray class encapsulates a JSON array. |
|
The QJsonDocument class provides a way to read and write JSON documents. |
|
|
The QJsonObject class encapsulates a JSON object. |
The QJsonParseError class is used to report errors during JSON parsing. |
|
The QJsonValue class encapsulates a value in JSON. |
|
The QByteArray class provides an array of bytes. |
|
|
The QByteArrayList class provides a list of byte arrays. |
|
The QByteArrayView class provides a view on an array of bytes with a read-only subset of the QByteArray API. |
The QCollator class compares strings according to a localized collation algorithm. |
|
The QCollatorSortKey class can be used to speed up string collation. |
|
The QLocale class converts between numbers and their string representations in various languages. |
|
The QRegularExpression class provides pattern matching using regular expressions. |
|
The QRegularExpressionMatch class provides the results of a matching a QRegularExpression against a string. |
|
The QRegularExpressionMatchIterator class provides an iterator on the results of a global match of a QRegularExpression object against a string. |
|
|
The QString class provides a Unicode character string. |
|
The QStringList class provides a list of strings. |
The QTextBoundaryFinder class provides a way of finding Unicode text boundaries in a string. |
|
The QDateTime class provides date and time functions. |
|
The QBitArray class provides an array of bits. |
|
|
The QCache class is a template class that provides a cache. |
The QCommandLineOption class defines a possible command-line option. |
|
|
The QContiguousCache class is a template class that provides a contiguous cache. |
|
The QHash class is a template class that provides a hash-table-based dictionary. |
|
The QMultiHash class is a convenience QHash subclass that provides multi-valued hashes. |
|
The QList class is a template class that provides a dynamic array. |
|
The QMap class is a template class that provides an associative array. |
|
The QMultiMap class is a template class that provides an associative array with multiple equivalent keys. |
|
The QQueue class is a generic container that provides a queue. |
|
The QSet class is a template class that provides a hash-table-based set. |
|
The QStack class is a template class that provides a stack. |