Exceptions aller Art
-
Ich möchte in meinem Programm einige Fehler per Exception abfangen, kann ich das Hauptprogramm quasi im try-Block lassen und am Schluss lauter catch-Blöcke anhängen, je nach Exception? Ich habe mal ein Beispiel mit einer Exception:
#include <iostream> #include "DataStruct.h" using namespace std; int main() { try { CDataStruct* pDataStruct = new CDataStruct(); // ... delete pDataStruct; } catch (bad_alloc &ba) // new fehlgeschlagen { std::cerr << ba.what(); } cin.get(); // Warten, bis ENTER gedrückt return 0; // Kein Fehler }
Kann ich jetzt auch schreiben:
try { // Versuchs doch... } catch (bla) { // Bla hat nicht geklappt } catch (blub) { // Blub hat nicht geklappt }
zwette
-
Ja, wenn du gemeint hast das du mehrer catchblöcke machen kannst
mfg
-
Ja, kannst du. Beachten musst du allerdings, dass catch(Basisklasse ex) auch AbgeleiteteKlasse fängt.
Wenn du also so etwas schreibst:
try { ... } catch( std::exception& ex ) { ... } catch( std::bad_alloc& ex ) { ... }
Wird der zweite catch-Block niemals betreten. AFAIK legt C++ leider nicht fest, dass solch unerreichbarer Code abgewiesen wird, aber evtl. warnt dich dein Compiler dann.
-
zwette schrieb:
try { CDataStruct* pDataStruct = new CDataStruct(); // ... delete pDataStruct; }
sowas darf man nicht screiben, wenn eine Exception zwischen new && delete geworfen werden kann.
es gibt doch smartpointers
-
Optimizer schrieb:
Ja, kannst du. Beachten musst du allerdings, dass catch(Basisklasse ex) auch AbgeleiteteKlasse fängt.
Wenn du also so etwas schreibst:
try { ... } catch( std::exception& ex ) { ... } catch( std::bad_alloc& ex ) { ... }
Wird der zweite catch-Block niemals betreten. AFAIK legt C++ leider nicht fest, dass solch unerreichbarer Code abgewiesen wird, aber evtl. warnt dich dein Compiler dann.
Das heißt im Klartext, mit den Unterklassen anfangen und die oberste Klasse immer zuletzt abfragen!?
ssm schrieb:
sowas darf man nicht screiben, wenn eine Exception zwischen new && delete geworfen werden kann.
es gibt doch smartpointers
Dann habe ich was falsch verstanden, ich dachte das Programm springt innerhalb eines try-Blocks immer in den catch-Block, wenn eine Exception kommt, egal, welche..!?
zwette
-
zwette schrieb:
Dann habe ich was falsch verstanden, ich dachte das Programm springt innerhalb eines try-Blocks immer in den catch-Block, wenn eine Exception kommt, egal, welche..!?
im catch-Block hast du keinen Zugriff zu
pDataStruct
und kannst nicht den Speicher freigeben
-
*andiestirnklopp* na klar, Du hast recht, daran habe ich garnicht gedacht, der Gültigkeitsbereich ist ja nur innerhalb des try-Blocks. Und wenn ich das so löse:
CDataStruct* pDataStruct; try { pDataStruct = new CDataStruct(); // ... delete pDataStruct; } catch(std::bad_alloc& ba) { // Error ausgeben und... delete pDataStruct; // Zeiger löschen } catch(std::irgendwas& iw) { // andere Exception }
BTW: Was sind Smartpointer?
zwette
-
Wenn du das so wie in deinem Beispiel löst, musst du dich an zwei Stellen um die Freigabe kümmern.
smart_pointer sind Objekte auf dem Stack die sich um das gewünschte Objekt auf dem Heap kümmern.
#include <memory> #include <iostream> #include <exception> using namespace std; int main() { try { auto_ptr<CDataStruct> rock_this_place (new CDataStruct); // rock the house with rock_this_place !! } catch (bad_alloc& ba) { cout << ba.what() << endl; } catch (excetion& e) { cout << e.what() << endl; } return 0; } // Sollte nun eine Exception auftreten wird dank dem Stack-unrolling // (oder wie das genau heißt) auch unser auto_ptr "rock_this_place" gelöscht. // In dessen dtor passiert dann auch das "delete".
// Ach ja.. auto_ptr<string> ptr_ONE(new string); auto_ptr<string> ptr_TWO = ptr_One; // Jetzt ist ptr_TWO Herr über den Zeiger und nicht mehr ptr_ONE.
-
Danke, der Tipp ist super!
Aber Du hast oben einen Fehler gemacht, es muss
std::auto_ptr<CDataStruct> rock_this_place (new CDataStruct); // Kein *
heißen.
zwette
-
Danke..
Ich hab's oben schon geändert!Leider komm ich nicht dazu meinen Code erst hier daheim zu testen.. Sonst hat schon ein anderer "meinen Code" gepostet.