2009-07-13 17 views
3

Zunächst einmal, da es verschiedene Arten von Smartpointern gibt, möchte ich diese Frage auf zwei von ihnen konzentrieren: Referenz zählte aufdringliche und nicht intrusive Smartpointer. Die Frage wird individuell für jeden Zeigertyp gestellt.Intelligente Zeiger. Wann, wo und wie?

Ich bin nicht wirklich sicher, wie ich meine Frage formulieren soll, also hier ist, was ich nicht frage: Ich frage nicht, warum, oder wann, sind intelligente Zeiger benötigt. Weder welche Art von Smart Pointer sollte ich verwenden und für was.

Hier ist, was ich fragen, und ich hoffe, es ist klar genug: Beim Umgang mit "intelligent verwalteten" Objekten, in welchem ​​Kontext sollte ich welche Pointer-Semantik verwenden? Das heißt, Smart-Pointer-Semantik, RAW-Pointer-Semantik, etwas anderes (z. B. ein Verweis auf einen Smart-Pointer)?

Es ist offensichtlich, dass, wenn ich einen Zeiger auf ein Objekt "speichern" (Objekt ist eine Referenz gezählt Speicherelement), wie ein globaler Zeiger oder als ein Klassenmitglied, sollte es ein intelligenter Zeiger sein, so würde es Anspruch auf Eigentumsrechte erheben, aber was ist mit anderen Situationen?

Wenn ich einen Zeiger als Funktionsargument übergebe, sollte es ein Smart-Pointer, ein roher Pointer, ein Verweis auf einen Smart Pointer oder etwas anderes sein? Was ist mit zurückgegebenen Zeigern? Lokale Zeiger? so weiter ...

Natürlich könnte ich intelligente Zeiger überall verwenden, was die sicherste Option ist, aber ich fühle, dass dies wirklich unnötig ist und zusätzlichen Aufwand verursacht.

+1

Gefühle sind in der Regel falsch passieren, Objekte als nicht-const Referenzen und ändern. Messe Es. –

Antwort

5

IMHO, manchmal ist es besser, Dinge schneller als eine kleine Leistungsverbesserung zu tun. Ich nehme an, Sie werden Dinge schneller tun, wenn Sie immer intelligente Zeiger verwenden.

Mein Vorschlag: Verwenden Sie intelligente Zeiger überall. Verwenden Sie dann einen Profiler, um festzustellen, ob ein erheblicher Overhead entsteht. Ändern Sie es :)

0

Meiner Erfahrung nach, wenn ich das Objekt an eine Funktion übergeben, die keinen Verweis auf das Objekt speichern muss (oder sonst wirkt sich der Aufruf der Funktion nicht auf die Lebensdauer des Objekts in irgendeiner Weise), dann ist es sicher, das Objekt als Referenz zu übergeben. Dies macht den Code weniger "gebunden" an den intelligenten Zeigertyp.

Auf der anderen Seite, mit immer dem Smart-Pointer-Typ ist „immer sicher“, so wenn im Zweifel ....

2

Wenn Sie tyring „Smart-Pointer-Semantik“ und „Rohzeiger Semantik“, um den Kontrast , Sie gehen fälschlicherweise davon aus, dass Sie alle "Smartpointer-Semantiken" zusammen gruppieren können. Ich bin nicht einverstanden. Der Unterschied zwischen boost::scoped_ptr und boost::shared_ptr ist von der gleichen Größenordnung wie die Differenz bwteeen boost::shared_ptr und T*

Wenn Sie „Speichern“ ein Zeiger auf ein Objekt als ein Klassenmitglied, haben Sie wirklich nicht sagen viel über die Semantik . Wenn das referenzierte Objekt logisch ein Mitglied ("owned") ist, dann würde ja ein intelligenter Zeiger gewünscht. Aber eine mit sehr spezifischer Semantik: Single Ownership. Dies bedeutet, dass kein gemeinsamer Besitz oder ein schwacher Zeiger vorhanden ist, um zwei andere übliche intelligente Zeiger zu benennen. Wenn Sie jedoch einen Zeiger auf ein Fehlerprotokollierungsobjekt speichern, möchten Sie wahrscheinlich einen schwachen Zeiger. Dies verhindert, dass Sie während des Herunterfahrens abstürzen - der schwache Zeiger ist NULL, wenn das Protokoll nicht mehr vorhanden ist.

Wenn Sie einen Zeiger von einer Funktion zurückgeben, diktiert die tatsächliche Semantik des Falls den erforderlichen Zeigertyp. Nicht die einfache Tatsache, dass es von einer Funktion zurückgegeben wird.

4

Ich schlage vor, Sie beschränken die Verwendung von Zeigern, smart oder anders, so viel wie möglich.Ich kenne Ihren Hintergrund nicht, aber viele Leute, die aus Sprachen wie Java oder C# kommen, verwenden Zeiger, wenn sie wirklich Werte verwenden und durch Verweis aufrufen sollen. Die Verwendung von Zeigern in einem C++ - Programm sollte relativ selten sein.

+1

Intelligente Zeiger sind nützlich, wenn Sie Objekte haben, die für eine lange Zeit leben müssen und eine gemeinsame und/oder übertragbare Eigentümerschaft haben müssen. Referenzen sind gut und gut, wenn das Eigentum auf einen einzigen Ort beschränkt ist. –

+4

Sehr wenige Objekte müssen lange leben und müssen geteilt oder übertragen werden. Der meiste Code beschäftigt sich mit kurzlebigen Werten. –

+1

Das mag in der Art von Code, mit der Sie arbeiten, der Fall sein. Es ist nicht für mich, weder hier noch in meinem letzten Nichtvertragsjob. (Das war in meinem letzten Auftragsjob der Fall.) Wenn jemand Zeiger benötigt oder wenn eine andere Art der Handhabung der Situation schlecht ist, dann sollten sie intelligente Zeiger verwenden. –

1

In vielen Situationen bezieht sich die Verwendung von Smartpointern auf Speicherverwaltung und/oder Ausnahmebehandlung. Die STL auto_ptr verwaltet die Vernichtung auch in komplexen try/catch-Umgebungen. Intelligente Zeiger sind nützlich, um den Lebenszyklus des spitzen Objekts an den intelligenten Zeiger zu delegieren. Es wird immer dann benötigt, wenn es schwierig ist, dem Paradigma zu folgen: "Zerstöre dein Objekt, wo du es erschaffen hast". Ein Smartpointer vom Referenztyp kann nützlich sein, wenn Sie ein gemeinsam genutztes Objekt nicht einfach verwalten können. Ich bevorzuge es, dieses Problem mit einer guten Architektur zu lösen, aber es gibt Fälle, in denen intelligente Zeiger der beste Weg sind.

2

Meine Liste von Zeigern:

  • normalen Gebrauch: normale Mitglieder und (const) Verweise auf sie
  • Sharing und das Objekt am Leben (Eigentümer, Container) zu halten: shared_ptr
  • -Sharing, aber nicht lebendig (Nutzer) zu halten: weak_ptr
  • scoped Nutzung: scoped_ptr
  • andere Verwendungen (Ausgabe-Parameter, ...): Rohzeiger
0
"When I'm passing a pointer as a function argument, should it be a smart-pointer, a raw 
pointer, a reference to a smart pointer, or maybe something else? What about returned 
pointers? Local pointe rs? so on..." 

mein 2p, es sei denn, Sie haben einen offensichtlichen Grund shared_ptrs nicht benutzen:

Sie nicht Zeiger auf Funktionen geben, übergeben Verweise auf die Objekte

keine Zeiger von Funktionen zurückgeben diese Objekte

Beim Erstellen von lokalen Objekten auf der Heap Verwendung scoped_ptr

+0

In vielen Anwendungen ist shared_ptr <> jedoch genau das Richtige. Dein Rat ist kaum allgemein gut. –

+1

Ich dachte, dass das in dem "es sei denn, du hast einen offensichtlichen Grund" bisschen gedeckt ist ... mein Rat richtet sich an jemanden, der shared_ptrs für alles verwenden möchte – Patrick

Verwandte Themen