Implicit Sharing

Definition

Das Kopieren von großen Objekten wie Bildern oder Strings ist sehr aufwendig. Um unnötigen Overhead zu vermeiden, verwenden viele Qt-Klassen Implicit Sharing.
Dabei wird anstatt des gesamten Objekts ein Zeiger auf die Daten kopiert („geteilt“) und ein Referenzzähler mitgeführt. Man nennt dies eine flache Kopie (shallow copy). Für jedes Objekt wird der Referenzzähler um 1 erhöht. Wird ein Objekt zerstört wird der Zähler entsprechend vermindert. Fällt der Referenzzähler auf 0, wird der Speicher freigegeben. Erst wenn man das kopierte Objekt verändert und es sich vom Original unterscheidet, wird tatsächlich eine Kopie angelegt (copy-on-write). Diese Art von Kopie nennt man tiefe Kopie (deep copy). All das passiert in vielen Qt-Klassen automatisch im Hintergrund und der Programmierer braucht sich darüber keine Gedanken zu machen.
Die Implementierung in Qt erlaubt auch die Verwendung von implizit geteilten Klassen in mehreren Threads ohne Probleme zu verursachen.

Implicit Sharing in Qt-Klassen

Wie bereits erwähnt verwenden viele Qt-Klassen bereits Implicit Sharing. Zu den wichtigsten Klassen zählen:

  • QString
  • QVariant
  • QByteArray
  • Bilder: QBitmap, QIcon, QImage, QPicture, QPixmap
  • Container: QVector, QList, QMap, …

Eigene Klassen mit Implicit Sharing implementieren

Um in selbst definierten Klassen implizit zu teilen sind mehrere Änderungen notwendig. Die eigentlichen Daten werden in eine von QSharedData abgeleitete Daten-Klasse verschoben. Ein Objekt von QSharedDataPointer bzw. QExplicitlySharedDataPointer mit der neuen Klasse als Template-Argument ist nun das einzige Element in unserer alten Klasse. Diese Klassen implementieren den Dereferenzierungsoperator für Zeiger (). Wir können dieses Objekt also verwenden, als wäre es ein Zeiger auf unsere Daten-Klasse. Der Unterschied zwischen QSharedDataPointer und QExplicitlySharedDataPointer liegt darin, dass bei letzteren Klasse copy-on-write über die Methode detatch() explizit durchgeführt werden muss.
Da das alles sehr abstrakt klingt ein Beispiel zur Erklärung: FIXME