C++-Programmierung: Fehlerbehandlung

Aus Wikibooks
Alte Seite
Diese Seite gehört zum alten Teil des Buches und wird nicht mehr gewartet. Die Inhalte sollen in das neue Buch einfließen: C++-Programmierung/ Inhaltsverzeichnis.
Eine aktuelle Seite zum gleichen Thema ist unter C++-Programmierung/ Ausnahmebehandlung verfügbar.

Um Fehler beim Programmablauf zentral abfangen und möglicherweise behandeln zu können, kennt C++ den Begriff der Ausnahme (exception). Solche Fehler wären z.B. eine Division durch 0, eine ungültige Benutzereingabe, eine fehlende Datenbankverbindung u.ä. Das Ausnahmenkonzept erleichtert insbesondere die Kommunikation zwischen Programmbibliothek und Anwendung.

Allgemeines[Bearbeiten]

Grundidee ist folgende: Stellt eine Funktion fest, dass sie selbst nicht angemessen auf einen Fehler reagieren kann, erzeugt sie eine Ausnahme und wirft diese aus, in der Erwartung, dass der aufrufende Kontext die Ausnahme auffangen und das Problem behandeln kann.

try
{
  // Potentiell gefährliche Anweisungen
}
catch
{
  // Fehlerbehandlung
}

Mit der Anweisung

throw ''Objekt'';

wird eine Ausnahme ausgeworfen. Üblicherweise verwendet man ein Objekt einer Klasse, die von einer allgemeinen Klasse Exception abgeleitet ist. Es darf aber ein beliebiger Wert sein, auch primitive Datentypen sind erlaubt.

Sobald die Ausnahme ausgeworfen ist, wird der aktuelle Block verlassen und die Ausnahme in der Aufruf-Hierarchie weitergereicht (dabei die entsprechenden Schichten vom Stack entfernt), bis ein mit try markierter Block gefunden ist. Dann wird die – unmittelbar hinter diesem Block stehende, mit catch bezeichnete – Fehlerbehandlungsroutine (handler) abgearbeitet, womit die Ausnahme als „behandelt“ gilt.

Mehrere Handler[Bearbeiten]

An einen try-Block können mehrere Handler angehängt werden. Diese sind dann für die Verarbeitung verschiedener Typen von Ausnahmen zuständig:

try
{
  // Potentiell gefährliche Anweisungen
}
catch(DatenbankverbindungsException dbException)
{
  //Exception-Verarbeitung, falls ein Problem mit der Datenbankverbindung besteht
}
catch(Exception allgemeineException)
{
  //Verarbeitung, falls eine andere Exception geworfen wurde
}

Dabei wird nicht der speziellste catch-Teil gesucht, sondern in der angegebenen Reihenfolge der erste „passende“ Handler verwendet. Man sollte daher zuerst die speziellen Klassen (weiter unten in der Vererbungshierarchie), danach die allgemeineren Klassen (oben in der Vererbungshierarchie) und erst dann (falls notwendig) die primitiven Datentypen abfangen. Passt überhaupt kein Handler zu der ausgeworfenen Ausnahme, wird sie an den nächsten umschließenden try-Block weitergereicht.