RAII-Fähige Klassen
-
Nabend,
ich bin am Überlegen wie man RAII-Fähige Klassen möglichst sauber implementiert. Im Endeffekt ist es ja so, dass auch beim Konstruieren und Dekonstruieren einer Instanz Fehler auftreten können. Im Falle eines Fehlers ist es natürlich am saubersten, eine Exception zu werfen. Jedoch nicht im Konstruktor oder Destruktor. Wie soll man unter diesen Umständen eine saubere Implementierung von RAII-Fähigen Klassen bereitstellen? Weiss jemand dafür eine saubere Lösung?
Viele Grüße
-
Destruktoren sollten generell keine Exceptions werfen. Bei komplizierten Konstruktoren ist ein beliebter (und guter) Trick, die Ressourcenverwaltung in eine private Basisklasse auszulagern. Auf die Art kann der Konstruktor der Hauptklasse Exceptions werfen, so viel er lustig ist, und der Destruktor der privaten Basisklasse kümmert sich um die Aufräumarbeiten.
-
Mh und wie bekommt man dann von außen mit, dass ein Fehler aufgetreten ist? Hast du evtl. ein kleines Beispiel?
-
#include <cstddef> #include <iostream> #include <stdexcept> class vec_base { protected: vec_base(int n) : data_(0), size_(n) { if(n > 0) data_ = new int[n]; } ~vec_base() { delete[] data_; std::cout << "Aufgeräumt!" << std::endl; } int *data_; std::size_t size_; }; class vec : private vec_base { public: vec(int const *front, int const *back) : vec_base(back - front) { int const *src; int *dest; for(src = front, dest = data_; src != back; ++src, ++dest) { if(*src == 123) throw std::logic_error("123 ist verboten!"); *dest = *src; } } }; int main() { int foo[] = { 1, 2, 3, 4, 123 }; { std::cout << "Das geht" << std::endl; vec v (foo, foo + 4); std::cout << "Ta da!" << std::endl; } try { std::cout << "Das geht schief" << std::endl; vec v2(foo, foo + 5); } catch(...) { std::cout << "Exception gefangen" << std::endl; } }
Ausgabe:
Das geht Ta da! Aufgeräumt! Das geht schief Aufgeräumt! Exception gefangen
Der Trick ist, dass das Objekt der Basisklasse bereits komplett ist, wenn der Konstruktor der abgeleiteten Klasse betreten wird. Wenn dann eine Exception geworfen wird, wird sein Destruktor ganz normal ausgeführt.
-
Alles klar, damit kann ich mich anfreunden :). Danke dir