Frage

C++ ist Eigentum Speicher
Aka "Eigentum Semantik"

Es liegt in der Verantwortung der Eigentümer der einen Teil des dynamisch zugewiesenen Speicher freigeben, dass der Speicher.Also ist die Frage wirklich wird, besitzt der Speicher.

In C++ ist Eigentum wird dokumentiert durch die Art eine RAW-Zeiger ist verpackt in so in eine gute (IMO) C++ - Programm, es ist sehr selten [SELTEN, nicht NIE], um zu sehen, ROHE Zeiger übergeben (als RAW-Zeiger haben keine abgeleiteten Besitz so können wir nicht sagen, wem gehört die Erinnerung und somit auch ohne sorgfältiges Lesen der Dokumentation, die Sie können nicht sagen, wer verantwortlich ist für den Besitz).

Umgekehrt ist es selten zu sehen ist, RAW-Zeiger gespeichert sind, die in einer Klasse jede RAW-Zeiger gespeichert ist, in seine eigene SMART-pointer-wrapper.(N. B.: Wenn Sie nicht der Eigentümer eines Objekts, Sie sollten nicht speichern Sie es, weil Sie nicht wissen können, wenn es geht aus von Umfang und zerstört werden.)

So ist die Frage:

  • Welche Art von Eigentum Semantische haben die Leute stoßen?
  • Welche standard-Klassen werden verwendet, um diese Semantik?
  • In welchen Situationen tun Sie Sie nützlich finden?

Lets halten 1 Art der semantischen Eigentum pro Antwort, so Sie können werden abgestimmt oben und unten individuell

Zusammenfassung:

Konzeptionell smart-Pointer sind einfache und naive Implementierungen sind einfach.Ich habe viele gesehen, die versuchten, Implementierungen, aber immer, Sie sind defekt in irgendeiner Weise, die nicht offensichtlich für gelegentliche Nutzung und Beispiele.Also ich empfehle immer mit gut getestet "Intelligenten Zeigern" aus einer Bibliothek, die eher als Ihre eigenen Rollen.std::auto_ptr oder einer der boost smart Pointer scheinen, um alle meine Bedürfnisse.

std::auto_ptr<T>:

Eine einzige person, die das Objekt besitzt.
Aber die übertragung des Eigentums ist erlaubt.

Verwendung:
======
Dies ermöglicht Ihnen, Schnittstellen zu definieren, die zeigen, dass die explizite übertragung des Eigentums.

boost::scoped_ptr<T>

Eine einzige person, die das Objekt besitzt.
Eigentumsübertragung ist NICHT erlaubt.

Verwendung:
======
Verwendet, um anzeigen explizite Eigentum.
Das Objekt wird zerstört, Destruktor oder, wenn Sie ausdrücklich zurücksetzen.

boost::shared_ptr<T> (std::tr1::shared_ptr<T>)

Mehrere Eigentumsverhältnisse.
Dies ist eine einfache Referenzzähler Zeiger.Wenn der Referenzzähler null erreicht-Objekt zerstört wird.

Verwendung:
======
Als Objekt kann mehrere Blumen mit einer Lebensdauer kann nicht bestimmt werden zur compile-Zeit.

boost::weak_ptr<T>

Verwendet mit shared_ptr<T>.
In Situationen, in denen ein Zyklus von Zeigern kann passieren.

Verwendung:
======
Verwendet, um stop-Zyklen beibehalten Objekte, wenn Sie nur die Zyklus ist die Aufrechterhaltung einer gemeinsamen refcount.

War es hilfreich?

Lösung

Für mich, diese 3 Arten bedecken die meisten meiner Bedürfnisse:

shared_ptr - Referenz-zählen, die Freigabe, wenn der Zähler null erreicht

weak_ptr - dasselbe wie oben, aber es ist ein 'slave' für eine shared_ptr, kann nicht freigeben

auto_ptr - bei der Erstellung und Freigabe geschehen im inneren die gleiche Funktion, oder wenn das Objekt als ein-Besitzer-immer nur.Wenn Sie vergeben einen Zeiger auf eine andere, der zweite ', Stiehlt', wird das Objekt aus der ersten.

Ich habe meine eigene Implementierung für diese, aber Sie sind auch in Boost.

Ich immer noch Objekte übergeben durch Referenz (const Wann immer möglich), in diesem Fall ist die genannte Methode muss davon ausgehen, das Objekt am Leben ist, nur während der Zeit des Anrufs.

Es gibt eine andere Art von Spitze, die ich verwende, die ich nennen hub_ptr.Es ist, wenn Sie haben ein Objekt, muss der Zugriff auf Objekte in es (in der Regel als virtuelle Basisklasse).Dies könnte gelöst werden, indem ein weak_ptr zu Ihnen, aber Sie haben nicht ein shared_ptr zu sich selbst.Wie Sie weiß, diese Objekte würden nicht länger Leben, als ihn, übergibt er eine hub_ptr zu Ihnen (es ist nur eine Vorlage wrapper zu einem regulären Zeiger).

Andere Tipps

Einfaches C++ - Modell

In den meisten Module, die ich sah, durch Standard, es wurde angenommen, dass der Empfang Zeiger war nicht empfangen Eigentum.In der Tat, Funktionen/Methoden Verzicht auf Eigentum an einem Zeiger beide waren sehr selten und explizit geäußert, dass die Tat in Ihrer Dokumentation.

Dieses Modell wird davon ausgegangen, dass der Benutzer Eigentümer nur, was er/Sie explizit zuweist.Alles andere wird automatisch entsorgt (im Rahmen verlassen, oder durch RAII).Dies ist ein C-Modell, erweitert durch die Tatsache, dass die meisten Zeiger sind im Besitz Objekte freigeben, die Sie automatisch oder bei Bedarf (bei der genannten Objekte Zerstörung, meistens), und dass die Lebensdauer der Objekte, die vorhersehbar sind (RAII ist dein Freund, wieder).

In diesem Modell, raw-Pointer sind frei zirkulieren und meist nicht gefährlich (aber wenn die Entwickler schlau genug ist, wird er/Sie Referenzen verwenden, anstatt, wenn möglich).

  • raw-Zeiger
  • std::auto_ptr
  • boost::scoped_ptr

Smart Wies C++ - Modell

In einem code, der voll von intelligenten Zeigern, die Benutzer können die Hoffnung zu ignorieren, die Lebensdauer von Objekten.Der Besitzer ist nie der Benutzer-code:Es ist die intelligente Zeiger, die sich RAII (wieder). Das problem ist, dass zirkuläre Referenzen gemischt mit Verweis gezählt smart-Pointer kann tödlich sein,, so dass Sie zu tun haben, sowohl mit den beiden gemeinsamen Zeiger und schwache Zeiger.So haben Sie immer noch das Eigentum zu prüfen (die schwache Zeiger könnten auch Punkt-zu nichts, auch wenn der Vorteil gegenüber der raw-Zeiger ist, dass es kann Ihnen sagen, so).

  • boost::shared_ptr
  • boost::weak_ptr

Fazit

Egal, die Modelle, die ich beschreibe, es sei denn, Ausnahme Erhalt einen Zeiger ist nicht empfangen von seinem Eigentum und es ist noch sehr wichtig zu wissen, wer besitzt, wer.Auch für C++ - code stark mit Referenzen und/oder smart pointers.

Nicht haben gemeinsamen Besitz.Wenn Sie dies tun, stellen Sie sicher, dass es nur mit code, den Sie nicht kontrollieren.

Das löst 100% von Probleme, da es Sie zwingt, zu verstehen, wie alles interagiert.

  • Shared Ownership
  • boost::shared_ptr

Wenn eine Ressource von mehreren Objekten.Die boost shared_ptr verwendet Referenz zu zählen, um sicherzustellen, dass die Ressource ist de-zugewiesen, wenn alle ist unter Dach und Fach.

std::tr1::shared_ptr<Blah> oft ist Ihre beste Wette.

Von anzukurbeln, gibt es auch die pointer container Bibliothek.Dies sind ein bisschen effizienter und einfacher zu bedienen als ein standard-container von intelligenten Zeigern, wenn Sie nur über die Objekte im Kontext Ihrer container.

Unter Windows gibt es die COM-Zeiger (IUnknown, IDispatch, und Freunde), und verschiedene intelligente Zeiger, um diese zu behandeln (z.B.der ATL CComPtr und der intelligente Zeiger automatisch erzeugt durch den "import" - Anweisung in Visual Studio basiert auf dem _com_ptr Klasse).

  • Ein Besitzer
  • boost::scoped_ptr

Wenn Sie brauchen, um Speicher dynamisch, wollen aber sicher sein, es wird ausgeplant auf jeder Ausfahrt, Punkt der block.

Ich finde das nützlich, als es kann leicht sein, umgesetzt und veröffentlicht, ohne jemals zu sorgen über eine Leck

Ich glaube nicht, dass ich jemals in der Lage Miteigentum an meinem design.In der Tat, aus der Spitze von meinem Kopf, die nur gültig ist, falls ich denken kann, ist Flyweight-pattern.

yasper::ptr ist ein leichtes, boost::shared_ptr wie alternative.Es funktioniert gut in meiner (noch) kleinen Projekt.

In der web-Seite an http://yasper.sourceforge.net/ es ist wie folgt beschrieben:

Warum schreiben Sie eine weitere C++ - smart-pointer?Es existieren bereits mehrere hohe Qualität smart pointer-Implementationen für C++, vor allem bei der Boost - Zeiger pantheon und Loki SmartPtr.Für einen guten Vergleich der smart-pointer Implementierungen und wenn Ihre Verwendung geeignete Lesen Sie bitte Herb Sutter Der Neue C++:Smart(er) - Pointer.In Kontrast mit die expansive features andere Bibliotheken, Yasper ist ein eng fokussierten reference counting Zeiger.Es entspricht eng mit Boost shared_ptr ist und Loki RefCounted/AllowConversion Richtlinien.Yasper ermöglicht es C++ - Programmierer zu vergessen-memory-management, ohne die Einführung der Boost ist groß Abhängigkeiten oder zu lernen, über Loki komplizierte politische Vorlagen.Philosophie

* small (contained in single header)
* simple (nothing fancy in the code, easy to understand)
* maximum compatibility (drop in replacement for dumb pointers)

Der Letzte Punkt kann gefährlich sein, da yasper ermöglicht riskant (noch sinnvoll) Aktionen (wie die Zuordnung zu raw Zeiger und manuelle release) verboten durch andere Implementierungen.Seien Sie vorsichtig, verwenden Sie nur diejenigen Funktionen, wenn die Sie wissen, was Sie tun!

Es ist eine Häufig verwendete form des single-transferable-Besitzer, und es ist vorzuziehen auto_ptr weil es vermeidet die Probleme, die verursacht durch auto_ptr's insane Korruption der Abtretung Semantik.

Ich spreche von niemand anderem als swap.Jede Art mit einem geeigneten swap Funktion gedacht werden kann als smart Referenz einige Inhalte, die es besitzt, bis zu dem Zeitpunkt, als der Besitz übertragen wird, um eine andere Instanz der gleichen Art, durch swapping Ihnen.Jede Instanz behält seine Identität, aber Sie wird gebunden, um neue Inhalte.Es ist wie eine sicher rebindable Referenz.

(Es ist eine intelligente Referenz anstatt einen intelligenten Zeiger, weil Sie nicht explizit dereferenzieren es um den Inhalt.)

Dies bedeutet, dass auto_ptr wird weniger notwendig - es ist nur erforderlich, um die Lücken zu füllen, wo die Typen nicht haben ein gutes swap Funktion.Aber alle std Behälter tun.

  • Besitzer:Aka löschen Kopieren
  • std::auto_ptr

Wenn der Schöpfer das Objekt will ausdrücklich hand Eigentums an jemand anderen.Dies ist auch eine Art Dokumentation im code, die ich gebe, dies für Sie und ich bin nicht mehr tracking it, so stellen Sie sicher, dass Sie es löschen, wenn Sie fertig sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top