return oder throw
-
Wenn ich jetzt z.B. ein paar Klassen habe und ich in irgendeiner Klasse z.B. ein Bild laden will, und das nicht klappt soll ich jetzt mit return ein false zurückgeben oder eine exception werden und die abfangen wo ich will?
Alsobool foo() { return false; } // oder void foo() { throw "failed"; }Und wie genau soll ich exceptions abfangen?
Mitcatch (...); // oder catch (Art der exception);Und wie kann ich die Art der exception die ich werfe bestimmen?
-
Du könntest dir die Artikel dieses Forums anschauen:
Exception-Handling
Modernes Exception-Handling Teil 1 - Die Grundlagen
-
Ich hab mir jetzt mal den ersten Artikes durchgelesen, und es sind noch ein paar Fragen offen geblieben.
1. Lohnt es sich, wenn man "new" benutzt, eine bad_alloc exception abzufangen, oder soll man das einfach sein lassen?
2. Wenn ich jetzt mit einem filestream z.B. ein Bild laden möchte, werfe ich einmal selbst string-exceptions mit Fehlerbeschreibung, es kann aber auch sein, dass der filestream eine exception wirft. Wie genau soll ich diese dann behandeln?
Mit zwei catch-Anweisungen etwa so:try { //... } catch (const std::string& exception) { //... } catch (...) { //... }Oder soll ich eine Klasse erstellen, die alle exceptions beinhaltet?
-
Ahnungslos^2 schrieb:
1. Lohnt es sich, wenn man "new" benutzt, eine bad_alloc exception abzufangen, oder soll man das einfach sein lassen?
Meistens nicht. Oft ist es das beste die Anwendungsdaten zu sichern und zu beenden.
2. Wenn ich jetzt mit einem filestream z.B. ein Bild laden möchte, werfe ich einmal selbst string-exceptions mit Fehlerbeschreibung, es kann aber auch sein, dass der filestream eine exception wirft. Wie genau soll ich diese dann behandeln?
Wirf keine std::strings. Wirf immer etwas dass von std::exception ableitet (oder erstelle Meinetwegen eine eigene Exception Klasse -> wichtig ist, dass alle Exception Typen in einer hierachie sind).
Dann stellt sich die Frage nämlich auch garnicht mehr. Du fängst einfach eine std::exception wenn es dir egal ist warum es fehlgeschlagen ist. Oft ist es das. Wenn es dir mal nicht egal ist - dann kannst du genauer spezifizieren welche Klassen zu erwartest:
catch(file_not_found const& e) { cerr << "konnte Datei "<<e.filename()<<" nicht finden"<<endl; } catch(file_corrupt const& e) { cerr << "datei "<<e.filename()<<" war vorhanden, ich konnte sie aber nicht parsen. Message: "<<e.what()<<endl; } catch(exception const& e) { cerr << "folgender Fehler ist augetreten: "<<e.what()<<endl; } catch(...) { cerr << "etwas verrücktes ist schief gegangen, gnade uns gott"<<endl; }Der Vorteil ist, du kannst immer so genau auf Fehler reagieren wie du willst. Wenn du zwischen einzelnen fehlern trennen willst (zB könnte es ja sein dass du auf ein file_not_found reagieren kannst indem du es wiederherstellst oder dergleichen) dann kannst du das jederzeit tun. Du musst es aber nie. catch(exception const&) fängt dir immer alles...
-
Und wenn ich jetzt z.B. einen offenen filestream habe, und dann eine exception werfe, wird der filestream automatisch geschlossen oder muss ich das selber machen?
-
Wenn du einen C++-Stream benutzt, der RAII kann, schliesst er sich. Bei C-Funktionen oder schlechtem C++-Code musst du das manuell tun.
-
Ich benutze den ganz normalen std::fstream. In der Referenz habe ich aber nichts darüber gefunden, was der Destruktor macht.