Ressourcenerfassung ist Initialisierung bedeutet, dass Objekte sich selbst als vollständiges Paket betrachten und nicht erwarten sollten, dass ein anderer Code einer Instanz mitteilt. Dies bedeutet normalerweise, dass der Destruktor etwas Bedeutendes enthält. Dies bedeutet auch, dass Sie eine Klasse speziell zum Verwalten von Ressourcen schreiben und wissen, dass Sie unter bestimmten, schwer vorhersehbaren Umständen, z. B. beim Auslösen von Ausnahmen, mit der Ausführung von Destruktoren rechnen können.
Angenommen, Sie möchten einen Code schreiben, in dem Sie den Windows-Cursor in einen Wartecursor (Sanduhr, Donut-of-Not-Working-Cursor usw.) ändern, Ihre Aufgaben erledigen und ihn dann zurücksetzen. Und sagen Sie auch, dass "do your stuff" eine Ausnahme auslösen könnte. Die RAII-Methode besteht darin, eine Klasse zu erstellen, deren ctor den Cursor zum Warten setzt, deren eine "echte" Methode das tut, was Sie wollen, und deren dtor den Cursor zurücksetzt. Ressourcen (in diesem Fall der Cursor-Status) sind an den Bereich eines Objekts gebunden. Wenn Sie die Ressource erwerben, initialisieren Sie ein Objekt. Sie können sich darauf verlassen, dass das Objekt zerstört wird, wenn Ausnahmen ausgelöst werden, und das bedeutet, dass Sie sich darauf verlassen können, dass die Ressource bereinigt wird.
Wenn Sie RAII gut verwenden, brauchen Sie es nicht finally
. Natürlich beruht es auf deterministischer Zerstörung, die Sie in Java nicht haben können. Sie können eine Art deterministische Zerstörung in C # und VB.NET mit bekommen using
.
Bei RAII geht es zum Teil darum zu entscheiden, wann ein Objekt für seine eigene Bereinigung verantwortlich wird. Die Regel lautet, dass das Objekt verantwortlich wird, wenn die Konstruktorinitialisierung abgeschlossen ist. Die Symmetrie von Initialisierung und Bereinigung, Konstruktor und Destruktor, bedeutet, dass die beiden eng miteinander verbunden sind.
Ein Punkt von RAII ist die Gewährleistung der Ausnahmesicherheit - dass die Anwendung selbstkonsistent bleibt, wenn Ausnahmen ausgelöst werden. Auf den ersten Blick ist dies trivial - wenn eine Ausnahme das Verlassen eines Gültigkeitsbereichs verursacht, müssen die lokalen Variablen in diesem Gültigkeitsbereich zerstört werden.
Aber was passiert, wenn der Ausnahmewurf innerhalb eines Konstruktors auftritt?
Nun, das Objekt wurde noch nicht vollständig konstruiert und kann daher nicht sicher zerstört werden. Der Konstruktor sollte nach Bedarf über Try-Blöcke verfügen, um sicherzustellen, dass alle erforderlichen Bereinigungen durchgeführt werden, bevor die Ausnahme propogiert wird. Sobald die Ausnahme außerhalb des Bereichs auftritt, in dem das Objekt erstellt wurde, erfolgt kein Destruktoraufruf, da das Objekt nicht an erster Stelle erstellt wurde.
Berücksichtigen Sie insbesondere die Konstruktoren für Elementdaten innerhalb des zu zerstörenden Objekts. Wenn einer dieser Auslöser eine Ausnahme auslöst, wird Ihr Hauptkonstruktorcode überhaupt nicht ausgeführt, aber ein Code, der einen impliziten Teil dieses Konstruktors bildet, wird über Folgendes verfügen. Alle Mitglieder, die erfolgreich erstellt wurden, werden automatisch zerstört. Elemente, die nicht erstellt wurden (einschließlich desjenigen, der die Ausnahme ausgelöst hat), sind es nicht.
Grundsätzlich ist RAII eine Richtlinie, die sicherstellt, dass alles, was vollständig konstruiert wurde, rechtzeitig zerstört wird, insbesondere wenn Ausnahmewürfe vorliegen, und dass jedes Objekt vollständig konstruiert wird oder nicht (es gibt keine Halbbilder). konstruierte Objekte, die Sie nicht sicher bereinigen können). Zugewiesene Ressourcen werden ebenfalls freigegeben. Und ein Großteil der Arbeit ist automatisiert, sodass sich der Programmierer nicht zu viele Sorgen machen muss.
quelle