Ich benutze boost:shared_ptr
in meinem Code ausgiebig . Tatsächlich werden die meisten Objekte, die auf dem Heap zugeordnet sind, von a gehalten shared_ptr
. Leider bedeutet dies, dass ich nicht this
in eine Funktion übergehen kann, die eine übernimmt shared_ptr
. Betrachten Sie diesen Code:
void bar(boost::shared_ptr<Foo> pFoo)
{
...
}
void Foo::someFunction()
{
bar(this);
}
Hier gibt es zwei Probleme. Erstens wird dies nicht kompiliert, da der T * -Konstruktor für shared_ptr
explizit ist. Zweitens, wenn ich erzwinge, dass es mit erstellt bar(boost::shared_ptr<Foo>(this))
wird, habe ich einen zweiten gemeinsamen Zeiger auf mein Objekt erstellt, der schließlich zu einem doppelten Löschen führt.
Dies bringt mich zu meiner Frage: Gibt es ein Standardmuster zum Abrufen einer Kopie des vorhandenen gemeinsam genutzten Zeigers, von dem Sie wissen, dass er in einer Methode für eines dieser Objekte vorhanden ist? Ist die Verwendung von aufdringlichen Referenzzählungen hier meine einzige Option?
std::
. Schau dir meine Antwort an.Antworten:
Sie können von enable_shared_from_this ableiten und dann "shared_from_this ()" anstelle von "this" verwenden, um einen gemeinsamen Zeiger auf Ihr eigenes Selbstobjekt zu erzeugen.
Beispiel im Link:
#include <boost/enable_shared_from_this.hpp> class Y: public boost::enable_shared_from_this<Y> { public: shared_ptr<Y> f() { return shared_from_this(); } } int main() { shared_ptr<Y> p(new Y); shared_ptr<Y> q = p->f(); assert(p == q); assert(!(p < q || q < p)); // p and q must share ownership }
Es ist eine gute Idee, wenn Sie Threads aus einer Mitgliedsfunktion erzeugen, stattdessen :: bind an ein shared_from_this () zu erhöhen. Dadurch wird sichergestellt, dass das Objekt nicht freigegeben wird.
quelle
Verwenden Sie einfach einen Rohzeiger für Ihren Funktionsparameter anstelle von shared_ptr. Der Zweck eines intelligenten Zeigers besteht darin, die Lebensdauer des Objekts zu steuern. Die Lebensdauer des Objekts wird jedoch bereits durch C ++ - Gültigkeitsregeln garantiert: Sie bleibt mindestens so lange bestehen wie das Ende Ihrer Funktion. Das heißt, der aufrufende Code kann das Objekt möglicherweise nicht löschen, bevor Ihre Funktion zurückkehrt. Somit ist die Sicherheit eines "dummen" Zeigers gewährleistet, solange Sie nicht versuchen, das Objekt in Ihrer Funktion zu löschen.
Sie müssen ein shared_ptr nur dann an eine Funktion übergeben, wenn Sie den Besitz des Objekts an die Funktion übergeben oder die Funktion eine Kopie des Zeigers erstellen möchten.
quelle
NULL
Zeiger möglich ist. Aber du machst einen guten Punkt.bar
in einen Rohzeiger zu ändern .boost hat eine Lösung für diesen Anwendungsfall. Aktivieren Sie enable_shared_from_this
quelle
Erstellen Sie wirklich mehr freigegebene Kopien von pFoo in der Leiste? Wenn Sie innen nichts Verrücktes tun, tun Sie einfach Folgendes:
void bar(Foo &foo) { // ... }
quelle
Mit C ++ 11
shared_ptr
undenable_shared_from_this
ist jetzt in der Standardbibliothek. Letzteres ist, wie der Name schon sagt, genau für diesen Fall.http://en.cppreference.com/w/cpp/memory/shared_ptr
http://en.cppreference.com/w/cpp/memory/enable_shared_from_this
Das Beispiel basiert auf den obigen Links:
struct Good: std::enable_shared_from_this<Good>{ std::shared_ptr<Good> getptr() { return shared_from_this(); } };
verwenden:
std::shared_ptr<Good> gp1(new Good); std::shared_ptr<Good> gp2 = gp1->getptr(); std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';
quelle
Die Funktion, die einen Zeiger akzeptiert, möchte eines von zwei Verhaltensweisen ausführen:
Bearbeiten: Hoppla, ich habe die Frage leicht falsch verstanden und sehe jetzt, dass diese Antwort die Frage nicht genau anspricht. Ich werde es trotzdem weglassen, falls dies für jemanden hilfreich sein könnte, der an ähnlichem Code arbeitet.
quelle