Frage

  

Mögliche Duplizieren:
   Wie Zeiger von Schub lösen :: shared_ptr?

Eine Funktion meiner Schnittstelle gibt einen Zeiger auf ein Objekt. Der Benutzer soll den Besitz des Objekts. Ich will nicht eine Boost.shared_ptr zurückzukehren, weil ich nicht will Kunden zwingen, Schub zu verwenden. Intern jedoch würde Ich mag den Zeiger in einem Shared_ptr speichern, um Speicherlecks bei Ausnahmen zu verhindern usw. Es scheint keine Möglichkeit zu geben einen Zeiger von einem freigegebenen Zeiger zu lösen. Irgendwelche Ideen hier?

War es hilfreich?

Lösung

Was Sie suchen ist eine release Funktion; shared_ptr hat keine Release-Funktion. Per Boost Handbuch :

  

Q. Warum Shared_ptr kein Release () Funktion zur Verfügung stellen?

     

A. shared_ptr kann nicht Eigentum verschenken, wenn es eindeutig ist (), weil die andere Kopie wird nach wie vor das Objekt zerstören.

     

Bedenken Sie:

shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2

int * p = a.release();

// Who owns p now? b will still call delete on it in its destructor.
  

Darüber hinaus wird der Zeiger nach Freigabe () zurückgegeben würde schwierig sein, zuverlässig freizugeben, als die Quelle shared_ptr mit einem benutzerdefinierten deleter erstellt werden konnte.

Zwei Optionen, die Sie sich anschauen sollten:

  • Sie std::tr1::shared_ptr verwenden könnte, die die Benutzer benötigen würde eine C ++ Bibliothek Implementierung unterstützen TR1 verwenden oder -Boost zu verwenden; zumindest würde dies ihnen die Möglichkeit, zwischen den beiden geben.
  • Sie können Ihre eigene boost::shared_ptr artigen gemeinsamen Zeiger implementieren und verwenden, die auf externe Schnittstellen.

Sie können auch in dieser Frage zu mit boost :: shared_ptr in einer öffentlichen Schnittstelle der Bibliothek.

Andere Tipps

Es gibt immer einen Weg: -)

Es ist in der Tat ein Grund, warum sie nicht Release () -Methode zur Verfügung stellen, aber es ist nicht unmöglich, zu erstellen. Machen Sie Ihre eigenen deleter. Etwas auf der Linie (nicht tatsächlich den Code kompiliert, aber das ist die allgemeine Vorstellung):

template <typename T>
class release_deleter{
public:
  release_deleter() : released_(new some_atomic_bool(false)){}
  void release() {released_->set(true);}
  void operator()(T* ptr){if(!released_->get()) delete ptr;}
private:
  shared_ptr<some_atomic_bool> released_;
}

..

shared_ptr<some_type> ptr(new some_type, release_deleter<some_type>());

..

release_deleter<some_type>* deleter = get_deleter<release_deleter<some_type>>(ptr);
deleter->release();
some_type* released_ptr = ptr.get();
  

Der Benutzer soll das Eigentum an dem Objekt nehmen. Ich will nicht eine Boost.shared_ptr zurückzukehren,

shared_ptr drückt shared Eigentum, und Sie möchten Ihre Schnittstelle Transfer Eigentums auszudrücken. std::auto_ptr wäre also mehr anwendbar hier.

  

Intern jedoch, ich mag den Zeiger in einem Shared_ptr speichern Speicherlecks bei Ausnahmen

zu verhindern

Auch hier shared_ptr möglicherweise nicht das beste Werkzeug für diesen Job sein. Um Lecks im Fall von Ausnahmen zu verhindern, scoped_ptr oder auto_ptr wäre besser geeignet.

Verwenden Sie eine shared_ptr zu einem scoped_ptr auf die Ressource (shared_ptr<scoped_ptr<Resource>>). Auf diese Weise kann shared_ptr die Referenzzählung erhalten, die automatisch die Ressource zerstören wird, wenn und nur wenn es noch an den scoped_ptr angebracht ist. Aber Sie können die scoped_ptr abnehmen, wenn Sie bereit sind, das Eigentum zu übergeben.

Wie James gut abgedeckt hat, kann man nicht wirklich einen freigegebenen Zeiger lösen.

Sie benötigen mehrere Eigentümer intern oder übertragen Sie den Besitz von Ihrer Klasse an den Client? In diesem Fall wird ein std::auto_ptr könnte die Rechnung passen.

Wenn Sie sich Sorgen über die überraschende Semantik von std::auto_ptr sind, könnten Sie es intern von boost::scoped_ptr halten, und nehmen Sie ihn an der Stelle, es auszuteilen - sie verlassen an den Client manuell um es zu löschen oder speichern sie in ihrem eigenen Smart-Pointer.

Wenn Sie mehrere Eigentümer auf Ihrer Seite zu tun haben könnten Sie eine intrusive Zählung verwenden. Intern können Sie dann boost::intrusive__ptr, verwenden aber die rohe Zeiger an der Schnittstelle Hand ab. Der Kunde kann dann entweder manuell mit ref Zählungen arbeiten, oder speichert sie in einem boost::intrusive_ptr selbst (aber Sie sich nicht auf sie machen abhängig)

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