Frage

Ich mache umfangreichen Gebrauch von boost:shared_ptr in meinem Code. In der Tat, die meisten der Objekte, die auf dem Heap zugeordnet sind, werden von einem shared_ptr gehalten. Leider bedeutet dies, dass ich nicht this in jede Funktion, die eine shared_ptr nimmt passieren kann. Betrachten Sie diesen Code ein:

void bar(boost::shared_ptr<Foo> pFoo)
{
    ...
}

void Foo::someFunction()
{
    bar(this);
}

Es gibt zwei Probleme hier. Zunächst wird dies nicht kompiliert, da die T * Konstruktor für shared_ptr explizit ist. Zweitens, wenn ich es erzwingen, mit bar(boost::shared_ptr<Foo>(this)) zu bauen Ich habe einen zweiten freigegebenen Zeiger auf mein Objekt erstellt, die schließlich zu einer Doppel löscht führen werden.

Das bringt mich auf meine Frage: Gibt es eine Standardmuster eine Kopie des vorhandenen freigegebenen Zeiger für das Erhalten Sie existiert wissen aus innerhalb einer Methode auf einem dieser Objekte? Nutzt intrusive Referenz hier meine einzige Option zu zählen?

War es hilfreich?

Lösung

können Sie leiten sich von enable_shared_from_this und Sie dann verwenden kann „shared_from_this ()“ statt „der“ einen gemeinsamen Zeiger auf Ihr eigenes selbst-Objekt zu laichen.

Beispiel in der Verbindung:

#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 Laichen Threads von einer Memberfunktion boost :: Bindung an einen shared_from_this () statt dieser. Es wird sichergestellt, dass das Objekt nicht freigegeben wird.

Andere Tipps

Nur eine Rohzeiger für Ihre Funktionsparameter anstelle des Shared_ptr verwenden. Der Zweck eines Smart-Pointer ist die Lebensdauer des Objekts zu steuern, aber die Objektlebensdauer bereits von C ++ Scoping-Regeln gewährleistet ist: es wird mindestens so lange, wie das Ende der Funktion existiert. Das heißt, dass der anrufende Code nicht möglicherweise das Objekt vor Ihrer Funktion zurückkehrt löschen; damit die Sicherheit eines „dummen“ Zeiger garantiert wird, solange Sie nicht versuchen, das Objekt in Ihrer Funktion zu löschen.

Die einzige Zeit, die Sie brauchen eine shared_ptr in eine Funktion zu übergeben, wenn Sie Eigentum an dem Objekt an die Funktion übergeben werden sollen, oder die Funktion wollen eine Kopie des Zeigers zu machen.

Boost hat eine Lösung für diesen Anwendungsfall, überprüfen enable_shared_from_this

Sind Sie machen wirklich mehr freigegebene Kopien von pFoo innerhalb bar? Wenn Sie nicht etwas verrückt nach innen tun, gerade dies tun:


void bar(Foo &foo)
{
    // ...
}

Mit C ++ 11 shared_ptr und enable_shared_from_this ist jetzt in der Standardbibliothek. Letzteres ist, wie der Name schon sagt, für diesen Fall genau.

http://en.cppreference.com/w/cpp/memory/shared_ptr

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

Beispiel basiert auf, dass in den Links oben:

struct Good: std::enable_shared_from_this<Good>{
    std::shared_ptr<Good> getptr() {
        return shared_from_this();
    }
};

Verwendung:

std::shared_ptr<Good> gp1(new Good);
std::shared_ptr<Good> gp2 = gp1->getptr();
std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';

Die Funktion gibt einen Zeiger zu akzeptieren will eine von zwei Verhaltensweisen tun:

  • Besitze das Objekt übergeben werden, und löschen Sie es, wenn es den Bereich verlässt. In diesem Fall können Sie nur X * akzeptieren und sofort wickeln Sie ein scoped_ptr um das Objekt (in dem Funktionskörper). Dies funktioniert „dieses“ oder im Allgemeinen jeder Halde zugewiesene Objekt zu übernehmen.
  • einen Zeiger Teile (es nicht besitzen) auf das jeweilige Objekt geführt wird. In diesem Fall, dass Sie tun nicht wollen sich auch alle scoped_ptr verwenden, da Sie will nicht das Objekt am Ende Ihrer Funktion zu löschen. In diesem Fall will, was man theoretisch ein shared_ptr ist (ich habe es gesehen eine linked_ptr an anderer Stelle genannt). Die Boost-Bibliothek hat eine Version von shared_ptr und dies spiegelt sich auch in Scott Meyers' Effective C ++ Buch (Punkt 18 in der 3. Auflage) empfohlen.

Edit: Oops ich die Frage etwas falsch verstanden, und ich sehe nun diese Antwort nicht genau die Frage Adressierung. Ich werde es in dem Fall überlassen sowieso, das ist für jedermann nützlich sein könnte, auf einem ähnlichen Code zu arbeiten.

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