Was ist mit "Resource Acquisition is Initialization (RAII)" gemeint?
Die Beispiele sind etwas nebulös, da es sich nicht um gültiges C++ handelt. Die Zeilen int *p = new int[-1];
nicht kompilieren.
Was ist mit "Resource Acquisition is Initialization (RAII)" gemeint?
Ein RAII-Kurs besteht aus drei Teilen:
RAII steht für "Resource Acquisition is initialization". Der "Ressourcenerwerb"-Teil von RAII ist der Teil, in dem Sie etwas beginnen, das später beendet werden muss, wie z. B.:
Der Teil "ist Initialisierung" bedeutet, dass die Erfassung innerhalb des Konstruktors einer Klasse erfolgt.
Die manuelle Speicherverwaltung ist ein Alptraum, den Programmierer seit der Erfindung des Compilers zu vermeiden suchen. Programmiersprachen mit Garbage-Collectors machen das Leben leichter, allerdings auf Kosten der Leistung. In diesem Artikel - Abschaffung des Garbage Collectors: Der RAII-Weg Der Toptal-Ingenieur Peter Goodspeed-Niklaus gibt uns einen Einblick in die Geschichte der Garbage Collectors und erklärt, wie Begriffe wie Eigentum und Ausleihen dazu beitragen können, Garbage Collectors zu eliminieren, ohne ihre Sicherheitsgarantien zu gefährden.
Viele argumentieren, dass RAII eine falsche Bezeichnung ist, aber eigentlich ist es ein richtiger Name für dieses Idiom, nur wird er nicht gut erklärt.
Wikipedia Verhalten im Detail erklärt: Resource Acquisition is Initialization (RAII) ist ein Programmieridiom, das in mehreren objektorientierten, statisch typisierten Programmiersprachen verwendet wird, um ein bestimmtes Sprachverhalten zu beschreiben. In RAII ist der Besitz einer Ressource eine Klasseninvariante und an die Lebensdauer des Objekts gebunden: Die Ressourcenzuweisung (oder -erfassung) erfolgt während der Objekterzeugung (insbesondere der Initialisierung) durch den Konstruktor, während die Ressourcendeallokation (Freigabe) während der Objektzerstörung (insbesondere der Finalisierung) durch den Destruktor erfolgt. Mit anderen Worten, der Erwerb von Ressourcen muss erfolgreich sein, damit die Initialisierung erfolgreich sein kann. Somit ist gewährleistet, dass die Ressource zwischen dem Ende der Initialisierung und dem Beginn der Finalisierung gehalten wird (das Halten der Ressourcen ist eine Klasseninvariante), und dass sie nur gehalten wird, wenn das Objekt lebendig ist. Wenn es also keine Objektlecks gibt, gibt es auch keine Ressourcenlecks.
Der Name bedeutet einfach, dass die Aktion "Ressourcenerwerb" eine Initialisierungsaktion ist und Teil der Initialisierung/Konstruktion des Objekts der Ressourcenklasse sein sollte. Mit anderen Worten, wenn man diese Redewendung verwendet, bedeutet die Arbeit mit einer Ressource, dass man eine Ressourcenklasse erstellt, um die Ressource zu speichern und die Ressource zum Zeitpunkt der Konstruktion des Klassenobjekts zu initialisieren. Implizit bedeutet dies, dass die Freigabe der Ressource symmetrisch im Destruktor der Ressourcenklasse erfolgen sollte.
Inwiefern ist das nützlich? Sie können diese Redewendung natürlich auch nicht verwenden, aber wenn Sie sich fragen, was Sie mit dieser Redewendung erreichen würden, bedenken Sie
RAII Es ist durchaus üblich, dass selbst größere C++-Projekte keinen einzigen Aufruf von new oder delete (oder malloc/free) außerhalb eines Konstruktor/Destruktor-Paares enthalten. Oder sogar überhaupt nicht.
Und Sie können die
exit: free_resouce() // Bereinigung der Ressource vor dem Beenden der Funktion
oder verwenden Sie eine RAII-Schloss damit Sie nie vergessen zu entsperren.
Ich habe diese Frage mehrmals gelesen und bin zu dem Schluss gekommen, dass die am häufigsten gewählte Antwort ein wenig irreführend ist.
Der Schlüssel für RAII ist:
"Es geht (meistens) nicht darum, Ausnahmen zu erwischen, sondern darum, das Eigentum an den Ressourcen zu verwalten."
Die am höchsten bewertete Antwort überschätzt ausnahmesichere Das hat mich verwirrt.
Tatsache ist, dass:
Sie müssen noch Folgendes schreiben try catch
zur Behandlung von Ausnahmen (siehe das 2 Codebeispiel unten), nur dass Sie sich nicht um die Freigabe von Ressourcen für diese Klassen kümmern müssen, wenn Sie RAII in Ihrem catch
Block. Andernfalls müssen Sie in der API jeder Nicht-RAII-Klasse nachsehen, welche Funktion Sie aufrufen müssen, um die erworbenen Ressourcen in catch
blockieren. RAII speichern diese Arbeit einfach.
Ähnlich wie oben, wenn Sie mit RAII programmieren, schreiben Sie einfach weniger Code, da Sie keine Funktionen zur Freigabe von Ressourcen aufrufen müssen. Alle Aufräumarbeiten werden im Destruktor durchgeführt.
Sehen Sie sich auch diese 2 Code-Beispiele an, die ich in den obigen Kommentaren für nützlich hielt.
https://ideone.com/1Jjzuc https://ideone.com/xm2GR9
P.S. Man kann mit der Python vergleichen with .. as
Anweisung, müssen Sie die Ausnahme abfangen, die innerhalb der with
Block zu.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
14 Stimmen
de.wikipedia.org/wiki/Ressourcenerwerb_ist_Initialisierung
17 Stimmen
Das ist es, was es für mich ausmacht. stroustrup.com/bs_faq2.html#finally
4 Stimmen
Microsoft-Referenz mit 3 Sätzen und 2 Beispielen aber sehr übersichtlich! msdn.microsoft.com/de-us/library/hh438480.aspx