Programme sollen robust sein, d.h. sie sollen falsche Eingaben, extreme Datenwerte oder generell unerwartete Situationen vernünftig abfangen. Das Programm soll weder ausser Kontrolle in einem undefinierten Zustand enden noch bei jeder Kleinigkeit abgebrochen werden.
Beispiel:
double fak( int n ) { // Funktion zur Berechnung der Fakultaet double t = 1.; for ( int i = 2; i <= n; i++ ) { t *= i; } return(t); }
Klassisch gibt es 2 Methoden:
Die
sanfte mittels Rückgabewert und
if Abfragen:
double fak( int n ) { // Funktion zur Berechnung der Fakultaet if ( n < 0 ) { cout << "Error in fak: Argument < 0 " << n << endl; return(-1.); } if ( n > NMAX ) { cout << "Error in fak: Argument > NMAX " << n<< endl; return(-2.); } double t = 1.; for ( int i = 2; i <= n; i++ ) { t *= i; } return(t); }
Nachteile:
double fak( int n ) { // Funktion zur Berechnung der Fakultaet if ( n < 0 ) { cout << "Error in fak: Argument < 0 " << n << endl; exit(1); } if ( n > NMAX ) { cout << "Error in fak: Argument > NMAX " << n<< endl; exit(2); } double t = 1.; for ( int i = 2; i <= n; i++ ) { t *= i; } return(t); }
Beispiel File-Öffnen, sinnvoll je nach Situation:
#include <vector> // vector headers #include <iostream> #include <cmath> #include <stdexcept> using namespace std; double root(double A, double B, double C) { // Returns the larger of the two roots of // the quadratic equation A*x*x + B*x + C = 0. // (Throws an exception if A == 0 or B*B-4*A*C < 0.) if (A == 0) { throw ("A can't be zero."); } else { double disc = B*B - 4*A*C; if (disc < 0) throw ("Discriminant < zero."); return (-B + sqrt(disc)) / (2*A); } } int main() { // cout << root( 0., 1., 1.) << endl; try { cout << root( 0., 1., 1.) << endl; } catch (char const *message ) { cout << "root failed: " << message << endl; // print error } try { cout << root( 1., 2., 1.5) << endl; } catch (char const *message ) { cout << "root failed: " << message << endl; // print error } }
if Abfragen vs Exceptions ist klassisch–philosophisches IT–Problem, siehe z.B. LBYL vs EAFP.
Leider ist das exception–Konzept erst nachträglich in C++ aufgenommen worden
Beispiel mit STL Vektoren:
#include <vector> // vector headers #include <iostream> #include <stdexcept> using namespace std; int main() { vector< double > v(10,1.); // <double> vector, 10 elements filled with 1 cout << v[5] << endl; // ok, exists cout << v[15] << endl; // doesn't exist but program continues cout << v.at(5) << endl; // ok cout << v.at(15) << endl; // doesn't exist, throws exception, abort try { cout << v.at(15) << endl; // doesn't exist, throws exception, catched } catch (out_of_range e) { // pre-defined logical exception class is thrown cerr << "Out of range exception " << e.what() << endl; // print error exit(1); // stop program or take other action } }
Anders in JAVA oder Python, exceptions sind integraler Bestandteil der Sprache: I/O, array bounds, mathematische Operationen, ...