2010-10-07 15 views
6

Ich habe eine C++ - Anwendung, die Zeiger verwendet, um ziemlich komplexe Datenstrukturen zu pflegen. Die Anwendung führt mathematische Simulationen auf großen Datenmengen durch (die mehrere GB Speicher benötigen könnten) und wird mit Microsoft Visual Studio 2010 kompiliert.Erste Schritte mit intelligenten Zeigern in C++

Ich überarbeite jetzt einen wichtigen Teil der Anwendung. Um Fehler zu vermeiden (hängende Zeiger, Speicherlecks, ...) möchte ich Smartpointer verwenden. Das Opfern von Speicher oder Leistung ist akzeptabel, solange es begrenzt ist.

In der Praxis werden die meisten Klassen in großen Pools verwaltet (ein Pool pro Klasse), und obwohl die Klassen sich aufeinander beziehen können, könnten Sie den Pool als Besitzer aller Instanzen dieser Klasse betrachten. Wenn der Pool jedoch entscheidet, eine Instanz zu löschen, möchte ich nicht, dass eine der anderen Klassen, die sich noch auf die gelöschte Instanz beziehen, über einen freien Zeiger verfügt.

In einem anderen Teil behalte ich eine Sammlung von Zeigern auf Instanzen, die von anderen Modulen in der Anwendung geliefert werden. In der Praxis behalten die anderen Module das Eigentum an der übergebenen Instanz, aber in einigen Fällen möchten Module nicht auf die Eigentumsrechte achten und möchten die Instanz nur an die Sammlung weitergeben, indem sie ihr "es gehört Ihnen jetzt, verwalten Sie es" sagen.

Was ist der beste Weg, um Smart Pointer einzuführen? Das bloße Ersetzen von Zeigern [durch Zufall] durch intelligente Zeiger scheint nicht der richtige Weg zu sein und liefert wahrscheinlich nicht alle (oder irgendeinen) Vorteile von intelligenten Zeigern. Aber was ist eine bessere Methode?

Welche Arten von Smartpointern sollte ich weiter untersuchen? Ich verwende manchmal std :: auto_ptr für die Freigabe von lokal zugeordnetem Speicher, aber dies scheint in C++ 0x abgewertet zu werden. Ist std :: unique_ptr eine bessere Alternative? Oder sollte ich direkt zu geteilten Zeigern oder anderen Arten von intelligenten Zeigern gehen?

Die Frage Replacing existing raw pointers with smart pointers scheint ähnlich, aber anstatt zu fragen, wie einfach es ist, frage ich, was der beste Ansatz wäre, und welche Art von Smart Pointer am besten geeignet sind.

Vielen Dank im Voraus für Ihre Ideen und Vorschläge.

Antwort

1

Hier sind die 3 Sorten in der neuen C++ 11-Standard gefunden (unique_ptr ersetzt auto_ptr)

http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr

http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr

http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr

Sie können den Text für jeden Zeiger lesen und es gibt eine Erklärung, wann man was dort verwenden soll. Für die lokale Speicherverwaltung ist unique_ptr die Wahl. Es ist nicht kopierbar, aber beweglich, wenn Sie es um den Empfänger herum bewegen, übernimmt es das Eigentum.

Shared_ptr wird verwendet, wenn Sie eine Objektinstanz mit niemandem teilen wollen, der das Objekt wirklich besitzt, und sicherstellen, dass es nicht gelöscht wird, solange noch jemand darauf verweist. Sobald der letzte Benutzer eines Objekts den Container shared_ptr zerstört, wird das enthaltene Objekt gelöscht.

weak_ptr wird in Verbindung mit shared_ptr verwendet. Es ermöglicht es einem, zu "sperren", um zu sehen, ob das Referenzobjekt shared_ptr noch existiert, bevor versucht wird, auf das interne Objekt zuzugreifen.

3

Ich empfehle die Verwendung unique_ptr wenn möglich (dies erfordert einige Programmanalyse) und shared_ptr, wenn dies unmöglich ist. Verwenden Sie im Zweifelsfall eine shared_ptr, um die Sicherheit zu maximieren: Wenn die Steuerung an einen Container übergeben wird, wird die Referenzzählung einfach auf zwei und dann zurück auf eins gesetzt und der Container wird schließlich das zugehörige Objekt automatisch delete. Wenn die Leistung zu einem Problem wird, sollten Sie die Verwendung von boost::intrusive_ptr in Erwägung ziehen.

+0

+1 guten Rat. Sie müssen eine Menge von Objekterzeugung/-zerstörung oder Zeigerkopieren machen, um einen Leistungsunterschied zwischen 'shared_ptr' und' intrusive_ptr' zu sehen. – Doug