2016-04-27 5 views
1

Ich denke, das Konzept eines Zeigers, der nach sich selbst wie std::shared_ptr aufräumt, ist cool, aber ich frage mich, ob es einen besseren Smart Pointer von Drittanbietern da draußen gibt.Smarter Smart Pointer

Das Problem mit der shared_ptr ist die von rekursiven Referenzen. Dies geschieht, wenn Sie so etwas wie dieses:

class A{ 
    public: 
    std::shared_ptr<A> other; 

    A() { } 
}; 

//Later 
std::shared_ptr<A> a = std::make_shared<A>(); 
std::shared_ptr<A> b = std::make_shared<A>(); 
a->other = b; //Memory leak 
b->other = a; //Memory leak 

Gibt es ein intelligenter Smart-Pointer aus, dass es spüren kann, wenn ich einen schwachen Zeiger verwendet haben sollte und leckt nicht (oder zumindest gibt eine Warnung aus)? (Nach einer kurzen Google-Suche kann ich nichts finden)

+1

Darf ich fragen, warum tun Sie das? Oder ist das nur ein einfaches Beispiel für etwas Komplizierteres? In diesem Beispiel missbrauchen Sie Smart Pointer. Du würdest 'delete this' nicht in einen Destruktor setzen. –

+0

Ihre Klasse 'A' kompiliert nicht. –

+0

'A(): selbst (* dies) {}' Huh? Was soll das tun? Was versuchst du zu erreichen? –

Antwort

3

Ein schwacher Zeiger ist genau das, was hier verwendet werden sollte.

Die Tatsache, dass std::shared_ptr grundlegende Referenzzählung implementiert, und nichts, mehr ist nicht etwas, das kürzlich entdeckt wurde. C++ ist keine verwaltete Sprache und verfügt nicht über Funktionen für die automatische Speicherbereinigung. Somit sind zirkulare Referenzen über std::shared_ptr problematisch. Die Lösung ist der schwache Zeiger.

+0

Ja. Das Problem beim Referenzzählen als GC-Mechanismus ist, dass es Zyklen nicht selbst bereinigen kann. Du musst es manuell machen. Kein intelligenter Zeiger könnte es für Sie entweder an dem Punkt des Erstellens des Zyklus erkennen, weil es nicht wirklich wissen würde, welcher Link der problematische war. Sie könnten sich eine intelligente Pointer-Implementierung vorstellen, die während des Programms genügend Informationen aufgezeichnet hat, so dass sie am Ende eines Laufs (oder am Checkpoint) über Lecks berichten könnte (Zyklen von Objekten, die nicht nach außen zeigen). Aber ich bin mir nicht bewusst (und es wäre unbedingt "nur debuggen"). – davidbak

+0

Es ist der Zweck des schwachen Zeigers, "std :: weak_ptr wird verwendet, um zirkuläre Referenzen von std :: shared_ptr zu brechen." –

+0

Nun, der Zweck eines schwachen Zeigers ist es, ein schwacher Zeiger zu sein. Zu erklären, was ein schwacher Zeiger ist und wie er funktioniert, geht etwas über den Umfang einer 200-Zeichen-Antwort auf stackoverflow.com hinaus. Jedes gute Buch über moderne C++ sollte Ihnen eine vollständige Erklärung und Beschreibung geben. –

0

Die Lösung ist das nicht:

class A{ 
    std::weak_ptr<A> self; 
    public: 
    A() : self(*this) { } 
}; 

die Lösung ist dies:

class A : std::enable_shared_from_this<A> 
{ 

    void use_me() 
    { 
    // say i need to pass a shared_ptr to myself to some other function... 
    foo(this->shared_from_this()); 
    } 
}; 

auto var = std::make_shared<A>(); 
+0

Das war wirklich nicht meine Frage (Ich versuche nur, über intelligentere intelligente Zeiger zu sehen, das Beispiel war belanglos) – DarthRubik

+0

wenn Sie "intelligentere intelligente Zeiger" sagen, was meinst du? Was genau willst du damit machen? –

+0

@DarthRubik - dann solltest du vielleicht an ein anderes Beispiel denken ... das aktuelle Beispiel hat den Nachteil (neben der Tatsache, dass es scheinbar nicht kompiliert), dass es eine "Antwort" gibt, die du plausibelerweise nicht wusstest . Daher ist es verwirrend. – davidbak