- Qt 5.15
- Qt Core
- Implicit Sharing
- Qt 5.15.18 Reference Documentation

# 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:

     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
         }
     }

## 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:

     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();

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, QVector, etc.) while you use STL-style iterator. See Implicit sharing iterator problem.

QBitArray | Array of bits
QBitmap | Monochrome (1-bit depth) pixmaps
QBrush | Defines the fill pattern of shapes drawn by QPainter
QByteArray | Array of bytes
QByteArrayList | List of byte arrays
QCache | Template class that provides a cache
QCollator | Compares strings according to a localized collation algorithm
QCollatorSortKey | Can be used to speed up string collation
QCommandLineOption | Defines a possible command-line option
QContiguousCache | Template class that provides a contiguous cache
QCursor | Mouse cursor with an arbitrary shape
QDBusPendingCall | Refers to one pending asynchronous call
QDBusUnixFileDescriptor | Holds one Unix file descriptor
QDateTime | Date and time functions
QDebug | Output stream for debugging information
QDir | Access to directory structures and their contents
QDnsDomainNameRecord | Stores information about a domain name record
QDnsHostAddressRecord | Stores information about a host address record
QDnsMailExchangeRecord | Stores information about a DNS MX record
QDnsServiceRecord | Stores information about a DNS SRV record
QDnsTextRecord | Stores information about a DNS TXT record
QFileInfo | System-independent file information
QFont | Specifies a query for a font used for drawing text
QFontInfo | General information about fonts
QFontMetrics | Font metrics information
QFontMetricsF | Font metrics information
QGlyphRun | Direct access to the internal glyphs in a font
QGradient | Used in combination with QBrush to specify gradient fills
QHash | Template class that provides a hash-table-based dictionary
QHostAddress | IP address
QHttp2Configuration | Controls HTTP/2 parameters and settings
QHttpPart | Holds a body part to be used inside a HTTP multipart MIME message
QIcon | Scalable icons in different modes and states
QImage | Hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device
QJsonArray | Encapsulates a JSON array
QJsonDocument | Way to read and write JSON documents
QJsonObject | Encapsulates a JSON object
QJsonParseError | Used to report errors during JSON parsing
QJsonValue | Encapsulates a value in JSON
QKeySequence | Encapsulates a key sequence as used by shortcuts
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
QMimeType | Describes types of file or data, represented by a MIME type string
QMultiHash | Convenience QHash subclass that provides multi-valued hashes
QMultiMap | Convenience QMap subclass that provides multi-valued maps
QNetworkAddressEntry | Stores one IP address supported by a network interface, along with its associated netmask and broadcast address
QNetworkCacheMetaData | Cache information
QNetworkCookie | Holds one network cookie
QNetworkInterface | Listing of the host's IP addresses and network interfaces
QNetworkProxy | Network layer proxy
QNetworkProxyQuery | Used to query the proxy settings for a socket
QNetworkRequest | Holds a request to be sent with QNetworkAccessManager
QOpenGLDebugMessage | Wraps an OpenGL debug message
QPainterPath | Container for painting operations, enabling graphical shapes to be constructed and reused
QPalette | Contains color groups for each widget state
QPen | Defines how a QPainter should draw lines and outlines of shapes
QPersistentModelIndex | Used to locate data in a data model
QPicture | Paint device that records and replays QPainter commands
QPixmap | Off-screen image representation that can be used as a paint device
QPolygon | Vector of points using integer precision
QPolygonF | Vector of points using floating point precision
QProcessEnvironment | Holds the environment variables that can be passed to a program
QQueue | Generic container that provides a queue
QRawFont | Access to a single physical instance of a font
QRegExp | Pattern matching using regular expressions
QRegion | Specifies a clip region for a painter
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
QSslCertificate | Convenient API for an X509 certificate
QSslCertificateExtension | API for accessing the extensions of an X509 certificate
QSslCipher | Represents an SSL cryptographic cipher
QSslConfiguration | Holds the configuration and state of an SSL connection
QSslDiffieHellmanParameters | Interface for Diffie-Hellman parameters for servers
QSslError | SSL error
QSslKey | Interface for private and public keys
QSslPreSharedKeyAuthenticator | Authentication data for pre shared keys (PSK) ciphersuites
QStack | Template class that provides a stack
QStaticText | Enables optimized drawing of text when the text and its layout is updated rarely
QStorageInfo | Provides information about currently mounted storage and drives
QString | Unicode character string
QStringList | List of strings
QTextBlockFormat | Formatting information for blocks of text in a QTextDocument
QTextBoundaryFinder | Way of finding Unicode text boundaries in a string
QTextCharFormat | Formatting information for characters in a QTextDocument
QTextCursor | Offers an API to access and modify QTextDocuments
QTextDocumentFragment | Represents a piece of formatted text from a QTextDocument
QTextFormat | Formatting information for a QTextDocument
QTextFrameFormat | Formatting information for frames in a QTextDocument
QTextImageFormat | Formatting information for images in a QTextDocument
QTextListFormat | Formatting information for lists in a QTextDocument
QTextTableCellFormat | Formatting information for table cells in a QTextDocument
QTextTableFormat | Formatting information for tables in a QTextDocument
QUrl | Convenient interface for working with URLs
QUrlQuery | Way to manipulate a key-value pairs in a URL's query
QVariant | Acts like a union for the most common Qt data types
QVector | Template class that provides a dynamic array