Wenn ~A()
und ~B()
laufe, kann ich sicher sein , dass der Speicher , in dem C
noch vorhanden gelebt ist?
Na sicher! Es wäre schwierig, eine Basisklasse zu verwenden, die versucht, ihren eigenen Speicher (den Speicher, in dem sie sich befindet) freizugeben. Ich bin mir nicht sicher, ob es überhaupt formal legal ist.
Implementierungen tun dies nicht: Wenn a shared_ptr<T>
zerstört oder zurückgesetzt wird, wird der Referenzzähler (RC) für den gemeinsamen Besitz von T
(atomar) dekrementiert; Wenn es im Dekrement 0 erreicht hat, wird die Zerstörung / Löschung von T
gestartet.
Dann wird die Anzahl der schwachen Eigentümer oder T-existierenden (atomar) dekrementiert, da sie T
nicht mehr existiert: Wir müssen wissen, ob wir die letzte Entität sind, die an dem Kontrollblock interessiert ist; Wenn die Dekrementierung ein Ergebnis ungleich Null ergab, bedeutet dies weak_ptr
, dass einige vorhanden sind (möglicherweise 1 Anteil oder 100%), die Eigentümer des Kontrollblocks sind, und sie sind jetzt für die Freigabe verantwortlich.
In beiden Fällen wird die atomare Dekrementierung für den letzten Miteigentümer irgendwann zu einem Wert von Null führen.
Hier gibt es keine Fäden, keinen Nichtdeterminismus, und offensichtlich wurde der letzte weak_ptr<T>
während der Zerstörung von zerstört C
. (Die ungeschriebene Annahme in Ihrer Frage ist, dass kein anderer weak_ptr<T>
beibehalten wurde.)
Zerstörung geschieht immer in genau dieser Reihenfolge. Der Steuerblock wird zur Zerstörung verwendet, da shared_ptr<T>
(im Allgemeinen) nicht bekannt ist, welcher (möglicherweise nicht virtuelle) Destruktor der (möglicherweise unterschiedlichen) am meisten abgeleiteten Klasse aufgerufen werden soll . (Der Steuerblock weiß auch, dass der Speicher nicht freigegeben werden soll, wenn die gemeinsame Anzahl Null erreicht make_shared
.)
Die einzige praktische Variation zwischen den Implementierungen scheint in den feinen Details von Speicherzäunen und der Vermeidung einiger atomarer Operationen in häufigen Fällen zu bestehen.
std::enable_shared_from_this
macht nicht viel. Ihr Beispiel sieht nicht gut aus für mich (vorausgesetzt , Sie nicht versuchen , etwas zu tun klug in~A
und~B
, wie unten Gussthis
zuC*
)