Exceptions




Was sind Exceptions?

Trotz sauberer Programmierung und abfangen von Fehlern, können in einem Programm Fehler auftreten, die man als Entwickler nicht vorhergesehen hatten oder von denen man überhaupt keine Kenntnis hatte. Um solche Fehler abfangen zu können, sind Exceptions (auch Ausnahmebehandlung genannt) vorhanden. Mit Hilfe von Exception kann auf Fehler flexibel reagiert werden. Im Gegensatz zu JAVA, wo es zwingend vorgeschrieben ist Exceptions zu nutzen, obliegt es in C++ dem Programmierer zu bestimmen wann und wo die Exceptions eingesetzt werden. Programmcode der unter Umständen einen Fehler hervorrufen könnte, kann so vor einem Programmabsturz geschützt werden.
Das sollte aber nicht dazu verleiten, Code zu schreiben, der nun ohne Fehlerprüfung auskommt. Nach wie vor ist es wohl sinnvoll Benutzereingaben zu prüfen, Zeiger auf zulässige Werte zu prüfen, Objekte wieder freizugeben usw.

Einschalten der Exceptions

Im Menü "Projekt->Projekt Optionen -> C++" kann die Exception-Behandlung ein oder ausgeschaltet werden.

Options

Die Erklärungen zu den einzelnen Punkten ist in der dazugehörigen Hilfe beschrieben. Wird die Exception-Behandlung abgeschaltet, so müssen die entprechenden Befehle zu Exception-Behandlung aus dem Programmcode entfernt werden. Dies gilt auch für die vom C++Builder erzeugte xxxx.cpp Datei, die die WinMain Methode enthält.

Befehle zur Exception-Behandlung

Für die Exception-Behandlung stehen die Befehle try, catch, __finally und throw zur Verfügung.

try lin dem Block der das Schlüsselwort try einschließt, steht der Code der eine Exception (Fehler) auslösen könnte
catch in dem Block der das Schlüsselwort catch einschließt, steht der Code der bei einer Exception (Fehler) ausgeführt wird
__finally in dem Block der das Schlüsselwort __finally einschließt, steht der Code der sowohl beim auftreten einer Exception als auch beim fehlerfreien Ablauf ausgeführt wird.
Wird __finally benutzt, kann catch nicht mehr benutzt werden.
throw Löst eine Exception aus

try

In dem try-Block wird der Code eingefasst, der unter Umständen einen Fehler hervorrufen könnte und es aus diesem Grunde nicht zu einem Programmabbruch kommen darf.

Als Beispiel soll ein String in einen Floatwert umgewandelt werden. Da der String nicht nur Ziffern, sondern auch nicht zulässige alphanummerische Zeichen enthalten kann, wird die Umwandlung in einen try Block durchgeführt.

double doubEingabe;
String sEingabe;
sEingabe="123,asd";
try
   {
   doubEingabe=StrToFloat(sEingabe);
   }

Der String enthält Zeichen, die bei der Umwandlung in einen double-Wert nicht zulässig sind.

catch

Um auf einen Fehler reagieren zu können, ist das Schlüsslewort catch vorhanden. In diesem Block wird angegeben, was ei dem Auftritt eines Fehlers passieren soll. Dabei bekommt die Anweisung catch einen Parameter zugeordnet, der festlegt, bei welcher Exception die Behandlung durchgeführt werden soll.

Beispiel:
catch (EAccessViolation& e)
catch (EAbstractError& e)
catch (EConvertError & e)

Sollen alle Exceptions behandelt werden, so kann
catch (...)
vorgegeben werden. Dann wird der catch-Block bei jeder Exception ausgeführt.

Auf einen try-Block können beliebig viele catch-Blöcke folgen.

Das Beispiel wird fortgesetzt und um zwei catch-Blöcke erweitert:

double doubEingabe;
String sEingabe;
sEingabe="123,asd";
try
   {
   doubEingabe=StrToFloat(sEingabe);
   }
catch(EConvertError& e)
   {
   MessageBox(NULL,"Wert konnte nicht umgewandelt werden!","Hinweis", MB_OK);
   }
catch(...)
   {
   MessageBox(NULL,"Unbekannter Fehler!","Hinweis", MB_OK);
   }

Wird eine Zeichenfolge eingegeben, die unzulässige Werte beinhaltet, wird die erste Messagebox ausgegeben. Tritt während der Umwandlung ein anderer Fehler auf, wird die zweite Messagebox ausgegeben.

__finally

Bei der Behandlung einer Exception kann entschieden werden, ob ein catch-Block oder ein __finally-Block aufgenommen wird.

Im Gegensat zum catch-block wird der __finally-Block immer ausgeführt.

Das ist sinnvoll wenn vor dem Auftreten eines Fehlers z.B. Speicherplatz reserviert wurde, der sowohl ein ein Fehler auftritt als auch wenn kein Fehler auftritt wieder freigegeben werden soll.

throw

Mit diesem Schlüsselwort kann eine Exception ausgelöst werden.

Beispiel:  throw Exception(EConvertError);

Eigene Exceptions

Sofer man eine eigene Klasse für eine Exception-Behandlung entworfen hat, kann diese auch in einen catch-Block eingebunden werden. Wenn die Klasse myexp entworfen wurde, so wird mit catch(myexp& e) die eigene Klasse aufgerufen.