Wird der Destruktor aufgerufen, wenn der Konstruktor eine Ausnahme auslöst?
Suche nach einer Antwort für C# und C++. (in C# ersetzen 'Destruktor' mit 'finalizer')
InformationsquelleAutor der Frage Qwertie | 2008-10-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Präambel: Herb Sutter hat einen tollen Artikel über das Thema:
http://herbsutter.wordpress.com/2008/07/25/constructor-exceptions-in-c-c-and-java/
C++ : ja und Nein
Während eines Objekts Destruktor wird nicht aufgerufen, wenn der Konstruktor wirft (das Objekt "nie existierte"), die Destruktoren der internen Objekte genannt werden könnte.
Als eine Zusammenfassung, alle inneren Teile des Objekts (d.h. member-Objekte) werden die Destruktoren aufgerufen, in der umgekehrten Reihenfolge Ihrer Konstruktion. Jedes Ding gebaut Konstruktor nicht der Destruktor aufgerufen, es sei denn, RAII ist in gewisser Weise verwendet.
Beispiel:
Ist die Reihenfolge der Erstellung werden:
Sagen wir, wir verwenden den folgenden code:
Einige mögliche Fälle:
Sollte m_aData werfen, auf Baustellen, m_aObject wird der Destruktor aufgerufen. Dann, den Speicher von "neue Klasse" aufgehoben wird.
Sollte m_pThing werfen an der neuen Sache (out of memory), m_aData, und dann m_aObject werden deren Destruktoren aufgerufen. Dann den Speicher neue Klasse freigegeben wird.
Sollte m_pThing werfen bei der Konstruktion, des Speichers, der durch das "neue Ding" wird aufgehoben. Dann m_aData, und dann m_aObject werden deren Destruktoren aufgerufen. Dann den Speicher neue Klasse freigegeben wird.
Sollte m_pGizmo werfen bei der Konstruktion, den Speicher "neues Spielzeug" wird aufgehoben. Dann m_aData, und dann m_aObject werden deren Destruktoren aufgerufen. Dann den Speicher neue Klasse freigegeben wird. Beachten Sie, dass m_pThing durchgesickert
Wenn Sie möchten, bieten die Grundlegende Ausnahme-Garantie Sie müssen nicht Leck, auch in den Konstruktor. So werden Sie haben, dies zu schreiben, auf diese Weise (mit STL oder sogar Boost):
Oder auch:
wenn Sie wollen/müssen, erstellen Sie diese Objekte innerhalb des Konstruktors.
Diese Weise, egal, wo der Konstruktor wirft, wird nichts zugespielt werden.
InformationsquelleAutor der Antwort paercebal
Es für C# (siehe code unten), aber nicht für C++.
Diese Drucke "Abgeschlossen"
InformationsquelleAutor der Antwort Jon Skeet
Den Destruktor der Klasse noch gebaut wird nicht aufgerufen, da das Objekt wurde nie vollständig aufgebaut.
Jedoch, den Destruktor seiner Basisklasse (falls vorhanden) WIRD aufgerufen, da das Objekt gebaut wurde, so weit als base-class-Objekt.
Darüber hinaus werden keine member-Variablen werden deren Destruktoren aufgerufen auch (wie andere bemerkt haben).
NB: das gilt für C++
InformationsquelleAutor der Antwort MarkR
In C++, die Antwort ist Nein - Objekts Destruktor ist nicht genannt.
Jedoch die Destruktoren eines Mitgliedstaats, Daten auf der Objekt wird genannt werden, es sei denn, die Ausnahme wurde ausgelöst, während der Erstellung einer Sie.
Mitglied Daten in C++ initialisiert wird (d.h. konstruiert) in der gleichen Reihenfolge wie Sie deklariert ist, also wenn der Konstruktor wirft, werden alle member-Daten, die initialisiert wurde, entweder explizit in der Member Initialization List (MIL) oder anderweitig - wird abgerissen wieder in umgekehrter Reihenfolge.
InformationsquelleAutor der Antwort Matt Dillard
Wenn der Konstruktor nicht fertig ausgeführt wird, wird das Objekt nicht existiert, so gibt es nichts zu zerstören. Dies ist in C++, ich habe keine Ahnung von C#.
InformationsquelleAutor der Antwort Greg Rogers
C++ -
NÖ. Der Destruktor wird nicht aufgerufen, für die teilweise errichteten Objekte. Eine Einschränkung: Der Destruktor wird aufgerufen, für Ihre Mitglieder Objekte, die komplett gebaut. (Beinhaltet automatische Objekte und systemeigenen Typen)
BTW - Was Sie wirklich suchen für ist genannt "Stack Unwinding"
InformationsquelleAutor der Antwort
Nicht Dinge tun, die dazu führen, Ausnahmen im Konstruktor.
Aufruf einer Initialize () - nachdem der Konstruktor, der Ausnahmen auslösen kann.
InformationsquelleAutor der Antwort Robert
Für C++ ist das gerichtet ist, in einer vorherigen Frage: Werde den code unten Ursache Speicherverlust in c++
Da in C++, wenn eine Ausnahme geworfen wird, in der ein Konstruktor, der Destruktor nicht aufgerufen, aber dtors für die member des Objekts (wurden gebaut) gecallt werden, dies ist ein primärer Grund für die Verwendung von smart-pointer-Objekte über raw-Zeiger - Sie sind ein guter Weg, um zu verhindern, dass memory leaks in einer situation wie dieser.
InformationsquelleAutor der Antwort Michael Burr