C++-Programmierung/ Ausnahmebehandlung/ Werfen und fangen und weiterwerfen

Aus Wikibooks
Zur Navigation springen Zur Suche springen


In dem vorherigen Kapitel haben wir Ihnen eine Möglichkeit gezeigt, wie man auf Fehler reagieren kann: geht etwas schief, wird einfach ein Rückgabewert ungleich

0

zurückgeliefert. In kleinen Programmen mag das noch akzeptabel sein, aber in größeren Bibliotheken wie z. B. Qt oder boost ist das Einarbeiten in die Dokumentation doch recht mühsam, um alle Fehlerwerte korrekt zu behandeln. Außerdem können solche Fehlerwerte einfach übersehen werden, was die Fehlersuche massiv erschwert. C++ bietet einen speziellen Mechanismus, um Fehler zu behandeln: Ausnahmen (engl. exceptions). Dadurch wird die Fehlererkennung von der Fehlerbehandlung entkoppelt. Der resultierende Programmcode wird deutlich übersichtlicher und da Exceptions nicht so einfach ignoriert werden können, erleichtern sie auch die Fehlerdiagnose.

Ausnahmen werfen[Bearbeiten]

Die allgemeine Syntax zum Werfen (von engl. to throw) von Ausnahmen lautet:

Crystal Project Tutorials.png
Syntax:
throw «Objekt»;
«Nicht-C++-Code», »optional«

Theoretisch kann alles geworfen werden, auch

int

s oder andere primitive Datentypen. In der Regel wird jedoch ein Objekt der Klasse

std::exception

aus der Headerdatei

stdexcept

geworfen. Die Konstruktoren übernehmen meist eine Zeichenkette als Fehlermeldung, die später mit der Methode

what()

abgefragt werden kann. Hier ein Beispiel, wie

throw

verwendet werden kann:

Nuvola-inspired-terminal.svg
1 #include <stdexcept>
2 #include <iostream>
3 
4 int flaeche(int breite, int laenge) throw(std::range_error){
5     if ((breite <= 0) || (laenge <= 0))
6         throw std::range_error("Breite oder Länge gleich 0 oder negativ");
7     return (breite * laenge);
8 }

Das

throw

kann auch in der Methodendeklaration stehen und zeigt dann an, welche Art von Ausnahmen beim Aufruf ausgelöst werden können. Wichtig ist, dass die möglichen Ausnahmen in runden Klammern stehen und ggf. durch Kommata getrennt aufgeführt werden.

Ausnahmen fangen[Bearbeiten]

Um auf die Exceptions reagieren zu können (sie zu "fangen") braucht man zwei weitere Schlüsselwörter:

try

und

catch

. Beide leiten Blöcke in geschweiften Klammern ein. Auf jeden

try

-Block folgt mindestens ein

catch

-Block. Im sogenannten

try

-Block stehen Code-Abschnitte, die Ausnahmen auslösen können und im

catch

-Block werden diese "aufgefangen" und behandelt. Nach

catch

stehen die Arten von Exceptions, die in dem jeweiligen Block behandelt werden.

Crystal Project Tutorials.png
Syntax:
try{
    // kritischer Abschnitt
} catch («Exceptionklasse» »bezeichner«){
    // Ausnahmebehandlung
}
«Nicht-C++-Code», »optional«

Hier ist ein Programm, welches die

flaeche()

-Funktion aus dem Beispiel oben verwendet:

Nuvola-inspired-terminal.svg
 1 #include <stdexcept>
 2 #include <ios>
 3 #include <iostream>
 4 
 5 using std::cout;
 6 using std::cerr;
 7 using std::cin;
 8 
 9 int flaeche(int breite, int laenge) throw(range_error);
10 
11 int main(){
12     int a, b;
13     // wenn ein wirklich schwerer Fehler auftritt soll cin eine Exception werfen
14     cin.exceptions(cin.exceptions() | ios_base::badbit);
15     cout << "Breite und Höhe eingeben: ";
16     cin >> a >> b;
17     try {
18         cout << "Flächeninhalt: " << flaeche(a, b) << endl;
19     } catch(const range_error& re){
20         cerr << "Ungültige Eingaben: " << re.what() << endl;
21         return 1;
22     } catch(const ios_base::failure& f){
23         cerr << "Schwerer Eingabefehler in cin:" << endl;
24         cerr << f.what() << endl;
25         return 2;
26     }
27     return 0;
28 }

Ausnahmen weiter werfen[Bearbeiten]

Oft kann es vorkommen, dass die auftretende Exception nicht vollständig behandelt werden kann. Dann ist es nützlich, die aufgetretene Ausnahme weiter zu werfen in der Hoffnung, dass irgendein Aufrufen sich darum kümmert. Die Syntax ist denkbar einfach:

Crystal Project Tutorials.png
Syntax:
try{
    // kritischer Abschnitt
} catch («Exceptionklasse» »bezeichner«){
    // teilweise Ausnahmebehandlung
    // "rethrow", Ausnahme erneut werfen
    throw;
}
«Nicht-C++-Code», »optional«