Im folgenden Code wird ein X in einem globalen Container registriert, der zu einem geteilten Besitzer desselben wird. Der Destruktor von X testet, dass er nicht länger Teil eines solchen Besitzes ist, was ich als eine gültige Voraussetzung für die Zerstörung ansehen würde.Sollte der Besitz vor oder nach den STL-Containern beendet werden, rufen Sie dessen Destruktor auf?
#include <vector>
#include <memory>
struct X {
~X();
};
std::vector<std::shared_ptr<X> > global_x_reg;
X::~X()
{
for (auto iter = global_x_reg.begin(), end = global_x_reg.end(); iter != end; ++iter)
if (iter->get() == this)
throw "Oops. X gets destroyed while it is still owned!";
}
int main(int argc, char** argv)
{
global_x_reg.push_back(std::shared_ptr<X>(new X));
global_x_reg.clear(); // calls X::~X().
}
Wenn es läuft (nach der Kompilierung mit VS2010), "Oops ..." wird ausgelöst, wenn der Behälter gelöscht wird.
Fragen:
- ist dieser Code legal? Wenn nicht, warum nicht? Wenn ja, sollte es werfen?
- sollte ein Standard-Container
clear()
so implementieren, dass diese Werte bei der Zerstörung seiner Werte nicht mehr als Containes sichtbar sind. - sollte
std::shared_ptr::get
, wennstd::shared_ptr
seinen Postee zerstört, zurückgebennullptr
?
Ich bin verwirrt. Wie kann ein Destruktor etwas Nützliches tun, wenn die Lebensdauer des Objekts zu Beginn des Aufrufs abgelaufen ist? Wenn Sie Memberfunktionen für ein Objekt, das zerstört wird, nicht aufrufen können, warum können Sie dann auf seine Datenmitglieder zugreifen? – Simple
@Simple Es ist nicht generell verboten, nach dem Ende seiner Lebensdauer auf ein Objekt zuzugreifen, obwohl das, was Sie mit einem solchen Objekt tun dürfen, sehr eingeschränkt ist. (Siehe die Referenzen im Zitat für [basic.life]/3, die ich vollständig in die Antwort eingefügt habe.) – Casey
@Casey: Danke, die LWG-Ausgabe 2382 gibt eine noch bessere Beschreibung der Situation, der ich gegenüberstand. Ich verstehe jetzt, dass Code nicht wieder in Standardcontainer eingeben sollte. Das OP-Beispiel wurde aus einer realen Codesituation mit stark rekursiven Datenstrukturen abgeleitet. Obwohl ich mit dem LWG-Plakat Peter Kasting übereinstimme, dass es am sinnvollsten ist, zu sagen, dass Objekte aus dem Container entfernt werden sollten, bevor sie zerstört werden, werde ich darauf hinweisen, dass dies eine derzeit gültige Voraussetzung ist, und versuchen, den Wiedereintritt zu vermeiden. –