šHgeocities.com/Vienna/Stage/4793/excp2.htmgeocities.com/Vienna/Stage/4793/excp2.htmdelayedx֏ÕJ’’’’’’’’’’’’’’’’’’’’Č0¤£OKtext/htmlĻBmo’’’’b‰.HMon, 18 Dec 2000 15:41:48 GMTāMozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)en, *֏ÕJ Standard C

Zurück ] Nach oben ] Weiter ]

 

Standard C++ Exceptions

Gruppierung von Ausnahmen

Eine Ausnahme ist ein Objekt einer Klasse, die ein Ausnahmeereignis repräsentiert. Man kann Ausnahmen oft in Familien einteilen. Hierbei erweist sich die Vererbung als Strukturierungshilfe als nützlich. Man könnte als Ausnahmen in einer mathematischen Bibliothek wie folgt organisieren:

class Matherr {};
class Overflow  : public Matherr {};
class Underflow : public Matherr {};
class Zerodivide: public Matherr {};

Nun könnte man jeden Matherr behandeln, ohne sich darum kümmern zu müssen, welche Art es genau ist. Zum Beispiel:

void f()
{
    try { 
        ... 
    } 
    catch ( Overflow ){ 
        // behandle Overflow und alles davon abgeleitete
    }
    catch ( Matherr )      
    {
        // behandle alle anderen Matherr
    }
}

Diese Möglichkeit der hierarchischen Gruppierung von Ausnahmen erhöht die Robustheit von Code, da es das Kodieren vereinfacht. Wie mühsam wäre es, den Handler von jedem Objekt einzeln zu programmieren. Außerdem wäre es eine Fehlerquelle, da man leicht einen Ausnahmetyp vergessen könnte.

Auch das Hinzufügen einer neuen Exceptionklasse könnte  zu einem Horrorszenario ausarten, wenn man diese überall im Code einprogrammieren müßte.

Polymorphismus und Ausnahmen

Ähnlich wie bei Funktionen unter C++ ist es möglich die Basisklasse einer Ausnahme statt die exakte Klasse als Argument in einem catch-Handler zu spezifizieren. Hierbei wird die geworfene Ausnahme durch Slicing zu der gefangenen Ausnahme.

Nehmen wir an, die Klasse Matherr habe die virtuelle Methode debug_print() definiert, die nur einen dum­men Text auswirft. Die davon abgeleitete Klasse Int_overflow überlädt diese mit einem eigenen Code, der die Operation und die Operanden mit ausgibt.

Dies könnte so aussehen...

    ...

    try {
        add( INT_MAX, 2 ); //Int_overflow wird ausgelöst
    }
    catch ( Matherr& m) { 
        m.debug_print(); 
    }

    ...

Dadurch, dass die Ausnahme als Referenz übergeben wird, ist sichergestellt, dass tatsächlich die überladene Funktion debug_print von der Klasse Int_overflow aufgerufen wird. Hätte man den Wert gefangen, stände nur die Methode von Matherr zur Verfügung.

Auch hier hat man den Vorteil, dass man, sobald man Operationen in den try-Block hineinnimmt, sichergestellt ist, dass alle Matherr gefangen und ausgegeben werden, ohne den catch-Handler anzufassen.

Mehrfachvererbung bzw. zusammengesetzte Ausnahmen

Nicht immer möchte man Ausnahmen in einer Baumstruktur gruppieren. Es kann vorkommen, daß eine Ausnahme zu zwei Gruppen gehört. Diese Zusammengehörigkeit wird durch Mehrfachvererbung dargestellt.

class Netfile_err : public Network_err, public File_system_err

Solch eine Klasse kann also mit Exceptionhandlern, die Network_err fangen, benutzt werden und genauso auch mit Handlern, die nur Dateisystemexceptions fangen.

Der Vorteil der Methode in diesem Beispiel ist, daß der Schreiber, der nur für das Dateisystem schreibt, unab­hängig davon ist, ob der Fehler lokal oder im Netzwerk passiert ist.