C ++ 03
std::auto_ptr
- Vielleicht eines der Originale, bei denen das erste Entwurfssyndrom auftrat, das nur begrenzte Möglichkeiten zur Müllabfuhr bietet. Der erste Nachteil ist, dass es zur delete
Zerstörung führt, was sie für das Halten von Array-zugewiesenen Objekten inakzeptabel macht ( new[]
). Es übernimmt den Besitz des Zeigers, sodass zwei automatische Zeiger nicht dasselbe Objekt enthalten sollten. Die Zuweisung überträgt das Eigentum und setzt den automatischen Zeiger rvalue auf einen Nullzeiger zurück. Was zum vielleicht schlimmsten Nachteil führt; Sie können aufgrund der oben genannten Unfähigkeit, kopiert zu werden, nicht in STL-Containern verwendet werden. Der letzte Schlag für jeden Anwendungsfall ist, dass sie im nächsten Standard von C ++ veraltet sein werden.
std::auto_ptr_ref
- Dies ist kein intelligenter Zeiger, sondern ein Designdetail, das in Verbindung mit verwendet wird std::auto_ptr
, um das Kopieren und Zuweisen in bestimmten Situationen zu ermöglichen. Insbesondere kann es verwendet werden, um eine Nicht- Konstantestd::auto_ptr
in einen l-Wert umzuwandeln, indem der Colvin-Gibbons-Trick verwendet wird, der auch als Verschiebungskonstruktor bezeichnet wird , um das Eigentum zu übertragen.
Im Gegenteil, vielleicht std::auto_ptr
war es nicht wirklich als universeller intelligenter Zeiger für die automatische Speicherbereinigung gedacht. Die meisten meiner begrenzten Erkenntnisse und Annahmen basieren auf Herb Sutters effektiver Nutzung von auto_ptr, und ich verwende sie regelmäßig, wenn auch nicht immer optimal .
C ++ 11
std::unique_ptr
- Dies ist unser Freund, der es ersetzen wird. std::auto_ptr
Es wird ziemlich ähnlich sein, außer mit den wichtigsten Verbesserungen, um die Schwächen std::auto_ptr
wie das Arbeiten mit Arrays, den Wertschutz über einen privaten Kopierkonstruktor, die Verwendung mit STL-Containern und -Algorithmen usw. zu korrigieren und Speicherbedarf sind begrenzt. Dies ist ein idealer Kandidat zum Ersetzen oder besser als Besitz von Rohzeigern. Wie das "Einzigartige" impliziert, gibt es nur einen Besitzer des Zeigers, genau wie der vorherige std::auto_ptr
.
std::shared_ptr
- Ich glaube, dies basiert auf TR1 und wurde boost::shared_ptr
verbessert, um auch Aliasing und Zeigerarithmetik einzuschließen. Kurz gesagt, es wird ein intelligenter Zeiger mit Referenzzählung um ein dynamisch zugewiesenes Objekt gewickelt. Da "gemeinsam genutzt" impliziert, dass der Zeiger mehr als einem gemeinsam genutzten Zeiger gehören kann, wenn die letzte Referenz des letzten gemeinsam genutzten Zeigers den Gültigkeitsbereich verlässt, wird das Objekt entsprechend gelöscht. Diese sind auch threadsicher und können in den meisten Fällen unvollständige Typen verarbeiten. std::make_shared
kann verwendet werden, um eine std::shared_ptr
Zuordnung mit einem Heap mithilfe des Standardzuweisers effizient zu erstellen .
std::weak_ptr
- Ebenfalls basierend auf TR1 und boost::weak_ptr
. Dies ist eine Referenz auf ein Objekt, das a gehört, std::shared_ptr
und verhindert daher nicht das Löschen des Objekts, wenn der std::shared_ptr
Referenzzähler auf Null fällt. Um Zugriff auf den Rohzeiger zu erhalten, müssen Sie zuerst auf den std::shared_ptr
Aufruf zugreifen , lock
der ein Leerzeichen zurückgibt, std::shared_ptr
wenn der eigene Zeiger abgelaufen ist und bereits zerstört wurde. Dies ist in erster Linie nützlich, um unbegrenzte Anzahl hängender Referenzen zu vermeiden, wenn mehrere intelligente Zeiger verwendet werden.
Boost
boost::shared_ptr
- Wahrscheinlich am einfachsten in den unterschiedlichsten Szenarien (STL, PIMPL, RAII usw.) zu verwenden. Dies ist ein gemeinsam genutzter, referenzierter, gezählter Smart Pointer. Ich habe in einigen Situationen einige Beschwerden über Leistung und Overhead gehört, aber ich muss sie ignoriert haben, weil ich mich nicht erinnern kann, was das Argument war. Anscheinend war es populär genug, um ein ausstehendes Standard-C ++ - Objekt zu werden, und es fallen keine Nachteile gegenüber der Norm in Bezug auf intelligente Zeiger ein.
boost::weak_ptr
- Ähnlich wie bei der vorherigen Beschreibung von std::weak_ptr
, basierend auf dieser Implementierung, ermöglicht dies einen nicht besitzenden Verweis auf a boost::shared_ptr
. Sie rufen nicht überraschend auf, lock()
um auf den "starken" gemeinsam genutzten Zeiger zuzugreifen, und müssen überprüfen, ob er gültig ist, da er möglicherweise bereits zerstört wurde. Stellen Sie nur sicher, dass der zurückgegebene freigegebene Zeiger nicht gespeichert wird, und lassen Sie ihn aus dem Gültigkeitsbereich verschwinden, sobald Sie damit fertig sind. Andernfalls kehren Sie direkt zum zyklischen Referenzproblem zurück, bei dem Ihre Referenzzählungen hängen bleiben und Objekte nicht zerstört werden.
boost::scoped_ptr
- Dies ist eine einfache Smart-Pointer-Klasse mit geringem Overhead, die wahrscheinlich für eine leistungsfähigere Alternative zur boost::shared_ptr
Verwendung entwickelt wurde. Dies ist std::auto_ptr
insbesondere deshalb vergleichbar , weil es nicht sicher als Element eines STL-Containers oder mit mehreren Zeigern auf dasselbe Objekt verwendet werden kann.
boost::intrusive_ptr
- Ich habe dies noch nie verwendet, aber meines Wissens ist es so konzipiert, dass es beim Erstellen eigener Smart-Pointer-kompatibler Klassen verwendet werden kann. Sie müssen die Referenzzählung selbst implementieren. Sie müssen auch einige Methoden implementieren, wenn Ihre Klasse generisch sein soll. Außerdem müssen Sie Ihre eigene Thread-Sicherheit implementieren. Auf der positiven Seite gibt Ihnen dies wahrscheinlich die individuellste Möglichkeit, genau auszuwählen, wie viel oder wie wenig "Schlauheit" Sie möchten. intrusive_ptr
ist in der Regel effizienter als shared_ptr
da es Ihnen ermöglicht, eine einzelne Heap-Zuordnung pro Objekt zu haben. (Danke Arvid)
boost::shared_array
- Dies ist ein boost::shared_ptr
für Arrays. Im Grunde genommen new []
, operator[]
und natürlich delete []
werden gebacken. Diese verwendet in STL - Containern werden kann , und soweit ich weiß , tut alles boost:shared_ptr
tut , obwohl Sie nicht verwenden können , boost::weak_ptr
mit diesen. Sie können jedoch alternativ a boost::shared_ptr<std::vector<>>
für ähnliche Funktionen verwenden und die Fähigkeit zur Verwendung boost::weak_ptr
für Referenzen wiedererlangen .
boost::scoped_array
- Dies ist ein boost::scoped_ptr
für Arrays. Wie bei boost::shared_array
allen erforderlichen Arrays ist die Güte eingebrannt. Diese ist nicht kopierbar und kann daher nicht in STL-Containern verwendet werden. Ich habe fast überall gefunden, wo Sie dies verwenden möchten, was Sie wahrscheinlich nur verwenden könnten std::vector
. Ich habe nie festgestellt, welches tatsächlich schneller ist oder weniger Overhead hat, aber dieses Array mit Gültigkeitsbereich scheint weitaus weniger involviert zu sein als ein STL-Vektor. Wenn Sie die Zuordnung auf dem Stapel beibehalten möchten, ziehen Sie boost::array
stattdessen in Betracht .
Qt
QPointer
- In Qt 4.0 eingeführt, ist dies ein "schwacher" intelligenter Zeiger, der nur mit QObject
und abgeleiteten Klassen funktioniert. Dies ist im Qt-Framework fast alles, sodass dies keine wirkliche Einschränkung darstellt. Es gibt jedoch Einschränkungen, nämlich, dass es keinen "starken" Zeiger liefert. Obwohl Sie überprüfen können, ob das zugrunde liegende Objekt gültig ist, können isNull()
Sie feststellen, dass Ihr Objekt direkt nach dem Bestehen dieser Prüfung zerstört wird, insbesondere in Umgebungen mit mehreren Threads. Ich glaube, die Leute halten dies für veraltet.
QSharedDataPointer
- Dies ist ein "starker" intelligenter Zeiger, der möglicherweise mit einer boost::intrusive_ptr
integrierten Thread-Sicherheit vergleichbar ist. Sie müssen jedoch Referenzzählmethoden ( ref
und deref
) angeben, die Sie durch Unterklassen ausführen können QSharedData
. Wie bei einem Großteil von Qt werden die Objekte am besten durch umfangreiche Vererbung und Unterklassen verwendet. Alles scheint das beabsichtigte Design zu sein.
QExplicitlySharedDataPointer
- Sehr ähnlich, QSharedDataPointer
außer dass es nicht implizit aufruft detach()
. Ich würde diese Version 2.0 QSharedDataPointer
als eine leichte Erhöhung der Kontrolle darüber bezeichnen, wann genau zu trennen ist, nachdem der Referenzzähler auf Null gefallen ist, ist kein ganz neues Objekt wert.
QSharedPointer
- Atomic Reference Counting, Thread-sicherer, gemeinsam nutzbarer Zeiger, benutzerdefinierte Löschvorgänge (Array-Unterstützung), klingt wie alles, was ein intelligenter Zeiger sein sollte. Dies ist, was ich hauptsächlich als intelligenter Zeiger in Qt verwende, und ich finde es vergleichbar mit, boost:shared_ptr
obwohl wahrscheinlich deutlich mehr Overhead wie bei vielen Objekten in Qt.
QWeakPointer
- Spüren Sie ein wiederkehrendes Muster? Genau wie std::weak_ptr
und boost::weak_ptr
dies wird in Verbindung mit verwendet, QSharedPointer
wenn Sie Referenzen zwischen zwei intelligenten Zeigern benötigen, die andernfalls dazu führen würden, dass Ihre Objekte niemals gelöscht werden.
QScopedPointer
- Dieser Name sollte auch vertraut aussehen und basierte tatsächlich im boost::scoped_ptr
Gegensatz zu den Qt-Versionen von gemeinsam genutzten und schwachen Zeigern. Es dient dazu, einen intelligenten Zeiger für einen einzelnen Eigentümer bereitzustellen, ohne dessen Aufwand QSharedPointer
die Kompatibilität, den ausnahmesicheren Code und alle Dinge, die Sie möglicherweise verwenden std::auto_ptr
oder boost::scoped_ptr
für die Sie möglicherweise verwenden, besser geeignet macht .