Exception Handling
-
Eigene Fehlerklassen brauchst du, wenn du mit den vorhandenen nicht auskommst,
d.h. du verursachst eine Exeption, die nicht durch die Standardfehler (vernünftig)
beschrieben werden kann.
-
Was gibt es den alles für Standartexceptions, ich habe keine gefunden.
-
Was gibt es den alles für Standartexceptions, ich habe keine gefunden
Wo hast du denn gesucht?
Ich habe bei google sofort folgendes gefunden: http://www.tempest-sw.com/cpp/draft/ch13-44-stdexcept.html
-
Original erstellt von Taurin:
Eigene Fehlerklassen brauchst du, wenn du mit den vorhandenen nicht auskommst,
d.h. du verursachst eine Exeption, die nicht durch die Standardfehler (vernünftig)
beschrieben werden kann.also ich würde generell mir eigene Fehlerklassen schreiben, auch wenn ich die eigentlich immer von std::runtime_exception ableite. Dann hat man die Möglichkeit auf die Fehler besser einzugehen IMHO.
-
Hallo ich habe mal so ein kleines (vollig unOOP, und sinnlose throws) Beispiel gemacht.
#include <iostream.h> #include <string.h> int eingabe(void); int main(void) { try { cout<<eingabe()<<endl; } catch(char *pcString) { if(strcmp(pcString, "Zahl ist 0")==0) { cout<<"catch: Zahl ist 0"<<endl; } else if(strcmp(pcString, "Zahl ist 1")==0) { cout<<"catch: Zahl ist 1"<<endl; } else { cout<<"undefinierter catch"<<endl; } } cout<<"Das bittere Ende"<<endl; return 0; } int eingabe(void) { int z; cin>>z; if(z==0) { throw "Zahl ist 0"; } else if(z==1) { throw "Zahl ist 1"; } else if(z==2) { throw "HEHE"; } return z; }
Meine Frage: Es funktioniert so, wofür brauche ich dann Fehlerklassen???
-
Es funktioniert so, wofür brauche ich dann Fehlerklassen???
Das zeigt dein Beispiel doch recht schön. Wirfst du einen int oder einen string, so hast du keinerlei den Fehler identifizierende Typinformationen. Vielmehr musst du alle high-level-Semantik selbst aus dem String raus fummeln. Das führt zu hässlichen, unübersichtlichen und häufig fehleranfälligen switch oder if Orgien. Außerdem kannst du auf der catch-Block-Ebene nicht zwichen Fehlern unterscheiden. Ein String ist ein String ist ein String. Der catch-Block fängt also alle Fehler die als Strings verpackt sind. Egal was der Inhalt des Strings ist. Damit verlierst du aber einen großen Vorteil von Exception-Handling. Nämlich, dass du Fehler selektiv behandeln kannst. Die die du behandeln kannst fängst du, die anderen lässt du ungefangen an weiter oben liegende Funktionen durchsickern.
-
um zu unterscheiden woher welcher Fehler kommt. Strings zu schmeißen ist nicht sehr Sinnvoll!
Angenommen, du hast zum Beispiel eine Funktion/Klasse etc. die dir eine Datei laden soll. Wenn du nun Strings als Exceptions benutzt, dann sieht es im Programm ja gleich aus, wenn die Klasse eine Exception schmeißt, wenn die Datei einfach nur nicht vorhanden ist oder kein Speicher verfügbar ist. So kannst du einfach entscheiden zB. beim ersten Fall einfach eine andere Datei zu öffnen oder beim 2. Fall Speicher frei zu geben oä.
(misst zu spät
)
[ Dieser Beitrag wurde am 08.07.2003 um 21:54 Uhr von kingruedi editiert. ]
-
Ok das hab ich glaube verstanden.
Da gibts aber noch eine kleine ungereimtheit für mich:
in der Funktion eingabe werfe ich ja einen Throw. Wenn die Eingabe-Funktion aber nicht in einem try-Block ausgeführt wird stürtzt das Programm ab.
Wie soll der Anwender meiner Klassen wissen, welche Methode Exceptions wirft oder nicht.
-
- Dokumentation
- man kann in der main-Funktion einen großen Auffangmechanismus einrichten, etwa so:
#include <exception> #include <iostream> using namespace std; int main() { try { // ... } catch (exception& e) { cerr << "Exception caught: " << e.what() << '\n'; } catch (...) { cerr << "Unknown exception caught.\n"; } }
(u.U. kann ein Absturz aber sinnvoller sein, da weiß man wenigstens, an welcher Stelle das unerwartete throw steht.)
[ Dieser Beitrag wurde am 08.07.2003 um 22:24 Uhr von Bashar editiert. ]
-
Was genau ist der Unterschied zwischen <iostream.h> und <iostream>
und wofür brauche ich das using namespace std?Ich habe das noch nie zuvor verwendet.
Was sind diese Includes ohne .h hinten dran?
-
sind die neuen C++ Standard Header, die alle im Namensbereich std stehen.
Deshalb das using namespace std;
-
Alex: willkommen zum ISO-C++ Standard, brandneu, druckfrisch, Tinte noch feucht, gerade erst (vor 5 Jahren) erschienen!
-
mal OT: die ganze STL schmeisst doch eigentlich exceptions, oder? d.h. ein wirklich korrektes hello world wäre dann
#include <iostream> int main () { try { std::cout << "Hello World!" << std::endl; } catch (...) { } // angenommen, ich hätte oben speicher allokiert, müsste ich hier vorbeugen }
oder übertreib ichs da eetwas
-
etwas.
aber im prinzip hast du recht
-
Ich denke nicht, dass das Exceptions werfen kann. Da wird ja kein Speicher angefordert, und ostream schmeißt ansonsten nur dann Exceptions, wenn man das explizit anfordert. Kandidaten für Exceptions sind hauptsächlich Konstruktoren und new-Ausdrücke (da fällt z.B. Zuweisung und Wertübergabe benutzerdefinierter Typen mit rein), dazu vereinzelte Dinge wie vector::at() oder dynamic_cast<Foo&>().
Und Reallokationen in Containern hab ich noch vergessen ... jedes push_back kann einem um die Ohren fliegen.[ Dieser Beitrag wurde am 09.07.2003 um 00:10 Uhr von Bashar editiert. ]
-
Original erstellt von Korbinian:
mal OT: die ganze STL schmeisst doch eigentlich exceptions, oder?die STL wirft (fast) garnix.
new wirft std::bad_alloc wenn es nicht mit std::nothrow aufgerufen wird
und die .at() methoden machen einen range check und werden dann uU ne exception, deswegen verwendet niemand .at() weils lahm ist.weiters kann man bei den streams bestimmte exceptions werfen lassen (die man per .exceptions() registrierern kann) - warum die das nicht von vornherein tun ist mir nicht ganz klar
d.h. ein wirklich korrektes hello world wäre dann
oder übertreib ichs da eetwas
jo, du uebertreibst.
theoretisch ist es moeglich, dass std::bad_alloc fliegt, naemlich dann wenn cout gepuffert ist und die allokation von "Hello World!" fehl schlaegt.realistisch gesehen wird das nie passieren.
-
Original erstellt von Shade Of Mine:
**theoretisch ist es moeglich, dass std::bad_alloc fliegt, naemlich dann wenn cout gepuffert ist und die allokation von "Hello World!" fehl schlaegt.
**Der Puffer wird hoffentlich im Konstruktor angelegt, nicht erst bei der ersten Ausgabe.
-
liest man nicht in streits, ob endl oder nicht, immer, dass cout ungepuffert ist und man deshalb kein endl braucht?
-
Eigentlich nicht. Man liest, dass cout den Puffer in allen nötigen Situationen selbständig ausleert, zB vor der Eingabe.
-
Nö. Nur cerr ist ungepuffert.