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 deleteZerstö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_ptrwar 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_ptrEs wird ziemlich ähnlich sein, außer mit den wichtigsten Verbesserungen, um die Schwächen std::auto_ptrwie 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_ptrverbessert, 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_sharedkann verwendet werden, um eine std::shared_ptrZuordnung 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_ptrund verhindert daher nicht das Löschen des Objekts, wenn der std::shared_ptrReferenzzähler auf Null fällt. Um Zugriff auf den Rohzeiger zu erhalten, müssen Sie zuerst auf den std::shared_ptrAufruf zugreifen , lockder ein Leerzeichen zurückgibt, std::shared_ptrwenn 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_ptrVerwendung entwickelt wurde. Dies ist std::auto_ptrinsbesondere 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_ptrist in der Regel effizienter als shared_ptrda es Ihnen ermöglicht, eine einzelne Heap-Zuordnung pro Objekt zu haben. (Danke Arvid)
boost::shared_array- Dies ist ein boost::shared_ptrfü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_ptrtut , obwohl Sie nicht verwenden können , boost::weak_ptrmit 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_ptrfür Referenzen wiedererlangen .
boost::scoped_array- Dies ist ein boost::scoped_ptrfür Arrays. Wie bei boost::shared_arrayallen 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::arraystattdessen in Betracht .
Qt
QPointer- In Qt 4.0 eingeführt, ist dies ein "schwacher" intelligenter Zeiger, der nur mit QObjectund 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_ptrintegrierten Thread-Sicherheit vergleichbar ist. Sie müssen jedoch Referenzzählmethoden ( refund 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, QSharedDataPointeraußer dass es nicht implizit aufruft detach(). Ich würde diese Version 2.0 QSharedDataPointerals 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_ptrobwohl wahrscheinlich deutlich mehr Overhead wie bei vielen Objekten in Qt.
QWeakPointer- Spüren Sie ein wiederkehrendes Muster? Genau wie std::weak_ptrund boost::weak_ptrdies wird in Verbindung mit verwendet, QSharedPointerwenn 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_ptrGegensatz 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 QSharedPointerdie Kompatibilität, den ausnahmesicheren Code und alle Dinge, die Sie möglicherweise verwenden std::auto_ptroder boost::scoped_ptrfür die Sie möglicherweise verwenden, besser geeignet macht .