Kein RAII - Kein Spaß

Wer “Resource Acquisition Is Initialization” - kurz RAII - nicht kennt, hat nicht das Recht sich als C++ Entwickler zu bezeichnen.

Und selbstverständlich gehört auch die Umkehrung dazu: “Resource Release Is Destruction” - kurz RRID.

Doch die erste Implementierung im GATE Projekt findet in C statt und hier fehlt dieses C++ Konzept wirklich sehr.


In C++ schreibt man sich einmal eine “Smart-Resource” Klasse …

 1class MyResource
 2{
 3private:
 4  resource_type        res;
 5  
 6public:
 7  MyResource()
 8  {
 9    this->res = create_my_resource();
10    if(this->res == NULL)
11    {
12      throw std::runtime_error("Failed to create resouce");
13    }
14  }
15  ~MyResource()
16  {
17    delete_my_resource(this->res);
18  }
19  
20  resource_type get()
21  {
22    return this->res;
23  }
24};

… und diese bindet man dann im Programm ganz natürlich ein:

 1void do_something()
 2{
 3  MyResource res1;
 4  MyResource res2;
 5  MyResource res3;
 6  MyResource res4;
 7  
 8  ...
 9}

Der Programmablauf do_something() sieht damit in C++ sehr sauber aus und der Compiler garantiert die korrekte Freigabe aller Ressourcen.

Aber was tun wir jetzt in reinem C ?

Tja, hier wird oft alles in eine Funktion gepackt. Aber hier müssen wir uns um eine korrekte Ressourcenverwaltung selbst kümmern. Mein alter eingelernter Ansatz sieht dann so aus:

 1int do_something()
 2{
 3  int succeeded = 0;
 4  resource_type res1 = NULL;
 5  resource_type res2 = NULL;
 6  resource_type res3 = NULL;
 7  resource_type res4 = NULL;
 8  
 9  do
10  {
11    res1 = create_my_resource();
12    if(res1 == NULL) break;
13    res2 = create_my_resource();
14    if(res2 == NULL) break;
15    res3 = create_my_resource();
16    if(res3 == NULL) break;
17    res4 = create_my_resource();
18    if(res4 == NULL) break;
19        
20    ...  
21        
22    succeeded = 1;
23  } while(0);
24  
25  if(res1 != NULL) delete_my_resource(res1);
26  if(res2 != NULL) delete_my_resource(res2);
27  if(res3 != NULL) delete_my_resource(res3);
28  if(res4 != NULL) delete_my_resource(res4);
29  
30  return succeeded;
31}

Und jetzt stellen wir uns das Beispiel mit 4 mal so vielen Ressourcen vor …

Dann wird unser do_something() schon ganz schön unübersichtlich. Auch die Frage, an welcher Stelle man eine Funktion “abbrechen” darf, ist in C++ dank Exceptions leichter und schöner beschreibbar, als in C. Und zusätzlich müssen wir uns den uninitialisierten Zustand auch noch irgendwie merken.

Fazit

Schätze deinen C++ Compiler!

Denn im Gegensatz zu uns Programmierern greift er das Thema Ressourcenverwaltung (meist) viel genauer und zuverlässiger auf.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!