Wann sollten wir std :: enable_shared_from_this verwenden?

8

Ich kannte nur std::enable_shared_from_this form diesen Link .
Aber nachdem ich den folgenden Code gelesen habe, weiß ich nicht, wann ich ihn verwenden soll.

%Vor%

Der obige Code ist "nicht so gut", weil vor dem Aufruf von shared_ptr kein getptr() existiert. So sollte das Gute sein:

%Vor%

Allerdings, wenn ich bereits ein shared_ptr -Objekt hatte, warum schreibe ich nicht einfach so: std::shared_ptr<Good> gp2 = gp1; , was bedeutet, dass ich std::enable_shared_from_this überhaupt nicht brauche.

Meiner Meinung nach ist die Verwendung von std::enable_shared_from_this , um sicherzustellen, dass mehr als ein shared_ptr -Objekte den gleichen Kontrollblock haben, so dass wir vermeiden können Doppel-lösche Problem . Aber wenn ich mich daran erinnern muss, am Anfang ein shared_ptr zu erstellen. Warum erinnere ich mich nicht daran, shared_ptr object zu verwenden, um ein neues Objekt zu erstellen, anstatt den rohen Zeiger zu verwenden?

    
Yves 28.12.2016, 15:08
quelle

3 Antworten

6

Der Hinweis darauf, wann std::enable_shared_from_this<T> nützlich ist, ist in seinem Namen: Wenn Objekte basierend auf einigen Anforderungen zurückgegeben werden, kann es erforderlich sein, einen Zeiger auf ein Objekt selbst zurückzugeben. Wenn das Ergebnis ein std::shared_ptr<T> sein soll, wird es notwendig, einen solchen Zeiger aus einer Member-Funktion zurückzugeben, wo normalerweise kein std::shared_ptr<T> verfügbar ist.

Wenn Sie von std::enable_shared_from_this<T> abgeleitet haben, können Sie eine std::shared_ptr<T> erhalten, die nur einen Zeiger vom Typ T enthält. Dies setzt jedoch voraus, dass das Objekt bereits über ein std::shared_ptr<T> verwaltet wird, und es würde Chaos erzeugen, wenn das Objekt auf dem Stapel zugewiesen wird:

%Vor%

In einem realistischen Szenario gibt es wahrscheinlich eine Bedingung, unter der ein std::shared_ptr<T> für das aktuelle Objekt zurückgegeben wird.

    
Dietmar Kühl 28.12.2016, 15:54
quelle
2

Es gibt einige Anwendungsfälle, bei denen Sie die Vorlage std::shared_ptr<T> nicht als undurchsichtigen Zeiger verwenden können.

In diesem Fall ist es nützlich, dies zu haben:

In einer Datei.cpp

%Vor%

In some_other.c

%Vor%     
Danh 28.12.2016 15:50
quelle
2

Nehmen wir an, ich möchte einen Berechnungsbaum darstellen. Wir haben eine Addition als eine Klasse, die von einem Ausdruck mit zwei Zeigern auf Ausdrücke abgeleitet ist, so dass ein Ausdruck rekursiv ausgewertet werden kann. Allerdings müssen wir die Auswertung irgendwo beenden, also lassen Sie uns Zahlen für sich selbst auswerten.

%Vor%

Live auf Coliru

Beachten Sie, dass die "offensichtliche" Art der Implementierung von Number::evaluate() mit return std::shared_ptr<Number>(this); fehlerhaft ist, da dies zu doppeltem Löschen führt.

    
milleniumbug 28.12.2016 15:51
quelle