Die Welt, in der Bjarne lebt, ist sehr ... akademisch, aus Mangel an einem besseren Begriff. Wenn Ihr Code so entworfen und strukturiert werden kann, dass Objekte über sehr bewusste relationale Hierarchien verfügen, sodass Eigentumsverhältnisse starr und unnachgiebig sind, fließt der Code in eine Richtung (von der oberen zur unteren Ebene), und Objekte kommunizieren nur mit denjenigen, die sich in der unteren Ebene befinden die Hierarchie, dann werden Sie nicht viel brauchen shared_ptr
. Es ist etwas, das Sie in den seltenen Fällen verwenden, in denen jemand gegen die Regeln verstoßen muss. Ansonsten können Sie einfach alles in vector
s oder andere Datenstrukturen einfügen, die Wertesemantik verwenden, und unique_ptr
s für Dinge, die Sie einzeln zuweisen müssen.
Es ist zwar eine großartige Welt, in der man leben kann, aber nicht das, was man die ganze Zeit tun muss. Wenn Sie nicht können Ihren Code auf diese Weise organisieren, weil das Design des Systems Sie versuchen zu machen , bedeutet , dass es unmöglich ist (oder einfach nur tief unangenehm), dann wirst du finden sich gemeinsame Verantwortung für Objekte benötigen mehr und mehr .
In einem solchen System ist das Halten nackter Zeiger ... nicht gerade gefährlich, wirft jedoch Fragen auf. Das Tolle daran shared_ptr
ist, dass es angemessene syntaktische Garantien für die Lebensdauer des Objekts bietet . Kann es kaputt sein? Na sicher. Menschen können aber auch const_cast
Dinge; Grundversorgung und Fütterung shared_ptr
sollten eine angemessene Lebensqualität für zugewiesene Objekte gewährleisten, deren Eigentum geteilt werden muss.
Dann gibt es weak_ptr
s, die ohne a nicht verwendet werden können shared_ptr
. Wenn Ihr System starr strukturiert ist, können Sie einen nackten Zeiger auf ein Objekt speichern, in dem Wissen, dass die Struktur der Anwendung sicherstellt, dass das Objekt, auf das Sie zeigen, Sie überlebt. Sie können eine Funktion aufrufen, die einen Zeiger auf einen internen oder externen Wert zurückgibt (z. B. ein Objekt mit dem Namen X suchen). In richtig strukturiertem Code steht Ihnen diese Funktion nur zur Verfügung, wenn die Lebensdauer des Objekts garantiert Ihre eigene überschreitet. Daher ist es in Ordnung, diesen nackten Zeiger in Ihrem Objekt zu speichern.
Da diese Steifigkeit in realen Systemen nicht immer erreicht werden kann, müssen Sie die Lebensdauer auf angemessene Weise sicherstellen . Manchmal brauchen Sie kein vollständiges Eigentum. Manchmal muss man nur wissen können, wann der Zeiger schlecht oder gut ist. Das ist , wo weak_ptr
kommt in . Es gibt Fälle, wo ich könnte ein verwendet haben , unique_ptr
oder boost::scoped_ptr
, aber ich hatte eine verwenden , shared_ptr
weil ich speziell einen „flüchtigen“ Zeiger zu geben , jemand benötigen. Ein Zeiger, dessen Lebensdauer unbestimmt war, konnte abfragen, wann dieser Zeiger zerstört wurde.
Ein sicherer Weg, um zu überleben, wenn der Zustand der Welt unbestimmt ist.
Könnte das durch einen Funktionsaufruf gemacht worden sein, um den Zeiger anstatt über zu erhalten weak_ptr
? Ja, aber das könnte leichter kaputt gehen. Eine Funktion, die einen nackten Zeiger zurückgibt, kann syntaktisch nicht vorschlagen, dass der Benutzer diesen Zeiger nicht langfristig speichert. Die Rücksendung von a shared_ptr
macht es auch viel zu einfach für jemanden, es einfach zu speichern und möglicherweise die Lebensdauer eines Objekts zu verlängern. Die Rückgabe eines weak_ptr
jedoch deutet stark darauf hin, dass das Speichern der shared_ptr
Daten, von denen Sie erhalten, lock
eine ... zweifelhafte Idee ist. Es wird Sie nicht davon abhalten, es zu tun, aber nichts in C ++ hält Sie davon ab, Code zu brechen. weak_ptr
bietet einen minimalen Widerstand gegen das Natürliche.
Das soll nicht heißen, dass shared_ptr
man es nicht überbeanspruchen kann . es kann sicherlich. Vor allem vorhin unique_ptr
gab es viele Fälle, in denen ich einfach a verwendet habe, boost::shared_ptr
weil ich einen RAII-Zeiger herumreichen oder in eine Liste aufnehmen musste. Ohne Bewegungssemantik und unique_ptr
, boost::shared_ptr
war die einzig wahre Lösung.
Und Sie können es an Stellen verwenden, an denen es nicht erforderlich ist. Wie oben angegeben, kann eine ordnungsgemäße Codestruktur die Notwendigkeit einiger Verwendungen von beseitigen shared_ptr
. Aber wenn Ihr System nicht als solches strukturiert werden kann und dennoch das tut, was es benötigt, shared_ptr
ist dies von erheblichem Nutzen.