Es gibt ein Beispiel, das zeigt, dass RAII auf diese Weise verwendet wird:
%Vor% ist sicher. aber meine Frage ist: Was passiert, wenn eine Ausnahme in p=fopen(n,a);
geworfen wird, dann wird Speicher, der i
zugewiesen ist, nicht zurückgegeben. Ist das richtig anzunehmen, dass RAII
Ihnen sagt, dass jedes Mal, wenn Sie X
als sicher haben wollen, alle von X
erworbenen Ressourcen auf dem Stack zugewiesen werden müssen? Und wenn X.a
erstellt wird, müssen Ressourcen von a
ebenfalls auf den Stack gelegt werden? und nochmal, und wieder, ich meine schließlich, wenn es eine Ressource auf dem Haufen gibt, wie es mit RAII gehandhabt werden könnte? Wenn es nicht meine Klasse ist, d. H.
Wenn Sie dies als eine intellektuelle Übung behandeln, bei der Sie std::vector
nicht verwenden möchten, müssen Sie Ihre Klassen aufteilen, damit sie eine einzige Verantwortung tragen. Hier ist meine "Integer Array" -Klasse. Seine Aufgabe ist es, den Speicher für ein Integer-Array zu verwalten.
Hier ist meine Datei-Handling-Klasse. Ihre Aufgabe ist es, ein FILE*
zu verwalten.
Beachten Sie, dass ich meinen Konstruktionsfehler in eine Ausnahme umwandle; fp_
ist ein gültiger Dateizeiger. Es ist eine Invariante, die ich beibehalten möchte, also bricht ich die Konstruktion ab, wenn ich diese Invariante nicht setzen kann.
Jetzt ist es einfach, File_ptr
exception safe zu machen, und die Klasse benötigt keine komplexe Ressourcenverwaltung.
Beachten Sie das Fehlen eines vom Benutzer deklarierten Destruktors, Kopierzuweisungsoperators oder Kopierkonstruktors. Ich kann die Reihenfolge der Mitglieder tauschen und in beiden Fällen ist es egal, welcher Konstruktor wirft.
Der springende Punkt von RAII ist, KEINE Ressourcen (wie das int
-array) an dangelnden Zeigern zuzuweisen. Verwenden Sie stattdessen std::vector
oder weisen Sie den Array-Zeiger einer Art std::unique_ptr
zu. Auf diese Weise werden die Ressourcen zerstört, wenn Ausnahmen auftreten.
Und nein, Sie müssen STL nicht verwenden, aber um RAII zu verwenden, müssen die niedrigsten Basisressourcen (wie Heap-zugewiesene Arrays) auch mit RAII erstellt werden, und der einfachste Weg dazu ist Verwenden Sie STL, anstatt eigene Smart-Pointer oder Vektoren zu schreiben.
Wenn eine Ausnahme nach dem new
auftritt, müssen Sie die Ausnahme abfangen und den Zeiger im Konstruktor löschen und dann erneut werfen. In diesem Fall wird der Destruktor nicht aufgerufen, da das Objekt niemals konstruiert wird.
andernfalls, wenn i
ein std :: vector ist, wird es automatisch bereinigt
Eine Möglichkeit, dies zu umgehen, besteht darin, alles, was durch eine Ausnahme ungültig gemacht werden könnte, in eine lokale Variable zu setzen, die selbst RAII verwendet, und sie dann am Ende den Mitgliedern zuzuweisen, wenn es sicher ist.
%Vor%Weitere Informationen finden Sie unter Ausnahmesicherheit .