Wie mehrere Throws verarbeiten?
-
Also ich habe eine funktion, die mehrere Exceptions werfen kann....
wie kann ich die alle bearbeiten? (anfangen)int testit(int tester) throw(int,char*) { if(tester==0) throw 0; if(tester==2) throw "Ausnahmefehler"; return tester*2; }
und was ist eine exceptionklasse?
-
Man Kann (bzw. man sollte) eine Klasse werfen, da man so mehr infos mitgeben kann. Fangen kann man das so:
//... try { funktion_die_mehrere_exceptions_wirft(); } catch(int a) { std::cout<<"Fehler: "<<a<<std::endl; } catch(char* c) { std::cout<<"Fehler: "<<c<<std::endl; } catch(spezielle_klasse_erxtra_fur_die_fn& se) { std::cout<<"Fehler (intern): "<<se.was_ist_passiert()<<std::endl; } catch(std::runtime_error& re) { std::cout<<"Laufzeitfehler: "<<re.what()<<std::endl; } catch(std::exception& e) { std::cout<<"Fehler (unbekannt): "<<e.what()<<std:endl; }; //...
-
Außerdem gibt es noch:
catch(...)
{}
Dort werden alle Exceptions gefangen, die ankommen, daher sollte es ganz an das Ende der anderen catch()s. Ist allerdings nicht unbedingt schöner Stil.
-
ok, wieso geht es, wenn ich hzuerst das catch mit dem int mache und dann char, aber nicht umgedreht?
Und gibt es irgendwo ein leichtes beispiel für eine exceptionklasse? oder kann jemand mal ein beispiel posten?
-
och_mann schrieb:
ok, wieso geht es, wenn ich hzuerst das catch mit dem int mache und dann char, aber nicht umgedreht?
Weil die allgemeinere Exception die speziellere Exception fängt.
Ein int kann ein char sein, aber nicht umgekehrt.
Einfach die Exceptions immer vom Speziellen zum Allgemeinen fangen.och_mann schrieb:
Und gibt es irgendwo ein leichtes beispiel für eine exceptionklasse? oder kann jemand mal ein beispiel posten?
Du kannst Alles werfen.
#include <string> using std::string; namespace och_mann { struct exception { public: enum FEHLERGRAD{low, normal, high}; const string& what() const {return error;} FEHLERGRAD priority() const {return FEHLERGRAD(fehlergrad);} exception(string Error, FEHLERGRAD Fehlergrad = normal) : error(Error) , fehlergrad(Fehlergrad) {} private: size_t fehlergrad; string error; }; } int main() { try { throw och_mann::exception("großer Fehler", och_mann::exception::high); } catch(och_mann::exception e) { e.priority(); e.what(); } return 0; }
Werfen kannst du alles.
Bastel dir einfach eine Klasse oder ein Struct und bau rein, was du möchtest.
-
Du kannst Alles werfen.
Nö. Nur Typen die kopierbar sind.
-
Du kannst auch by Referenz fangen. Beispiel:
class MyException1:public std::runtime_error { public: MyException1(const std::string&msg):runtime_error(msg){} }; class MyException2:public std::runtime_error { public: MyException2(const std::string&msg):runtime_error(msg){} }; void foo1() { if(rand() % 2 == 0) throw MyException1("Hallo"); } void foo2() { throw MyException2("Och"); } int main() { try{ foo1(); foo2(); }catch(std::exception&except){ cerr<<"Stopped on exception throw : "<<except.what()<<endl; } }
Dies erlaubt dir mehrere Arten von Ausnahmen mit einem catch zu fangen. Man sollte auch wissen, dass std::runtime_error von std::exception erbt.
Generel ist es eine gute Idee seine Ausnahmen von std::runtime_error oder std::exception erben zu lassen. Normalerweise wirft man keine fundamentale Typen.
-
Ben04 schrieb:
Du kannst auch by Referenz fangen.
sollte man nicht sogar by reference fangen?
"Throw by value,catch by reference"
-
hm...ok, ich werd das mal versuchen, wobei ich da noch ncih so ganz durchblick!
-
und ist es auch sinnvoll, für jede exception eine eigene klasse zu machen? oder mehrere in eine?