Revision history for ObjProg03Exceptions
Additions:
CategoryObjektorientierteProgrammierung
Deletions:
Additions:
CategoryDelete
Deletions:
Additions:
float pf(float y, float x) throw (""DiviNull,"" Unterlauf);
float pf(float y, float x) throw (""DiviNull,"" Unterlauf){...}
float pf(float y, float x) throw (""DiviNull,"" Unterlauf){...}
Deletions:
float pf(float y, float x) throw (DiviNull, Unterlauf){...}
Additions:
===Genereller Exception-Handler ===
Als letzter catch- Block kann ein so genannter genereller Exception-Handler definiert werden.
Er übernimmt alle ausgelösten Exceptions, welche von keinem vorherigen Block übernommen werden.
catch(…)
{ //Handler für jede Art von Exceptoin
//drei Punkte statt Typ
Kann im Programm kein Handler gefunden werden, so wird das Programm beendet.
""⇒"" Demo 3. Handler-Suche
""⇒"" Demo 4. Erfolglose Handler-Suche
===Anordnung von try-Blöcken===
In einem Programm können mehrere try-Blöcke mit entsprechenden Exception-Handlern eingesetzt werden. Die Blöcke können sequentiell oder verschachtelt angeordnet werden.
**Handler-Suche in verschachtelten Blöcken**
1) Einige Exceptions können durch die Handler eines inneren try-Blocks separat behandelt werden.
2) Alle übrigen Exceptions suchen nach dem passenden Handler des äußeren try-Blocks.
===Wiederauswerfen von Exception===
Eine im inneren try-Block ausgelöste Exception kann an den umgebenen try- Block weitergereicht werden.
Die aktuell bearbeitete Exception wird nochmals ausgeworfen, um vom Handler des umgebenden Blocks
weiter bearbeitet zu werden.
{{image class="center" url="oop14.gif" width="350"}}
===Exception- Spezifikation===
Die Exceptions, die von einer Funktion ausgelöst werden kann, gehören zu den Eigenschaften einer Funktion. Sie müssen dem Anwender bekannt sein, damit geeignete Reaktionen programmiert werden können.
An die Funktions-Deklaration (Prototyp) wird einer so genannten Exception- Spezifikation angehängt.
**Deklaration**:
float pf(float y, float x) throw (DiviNull, Unterlauf);
**Definition**:
float pf(float y, float x) throw (DiviNull, Unterlauf){...}
Ist die Exception-Liste leer, so wird keine Exception zugelassen.
**Deklaration**:
float pf(float y, float x) throw ( );
**Definition**:
float pf(float y, float x) throw ( ){...}
Ist keine Exception- Spezifikation angegeben, so sind alle Exceptions zulässig.
===Standard-Fehlerklassen===
In ""C++"" wird eine Reihe von Standard-Fehlerklassen definiert.
**Einige Klassen: **
""<table class="data" width="80%" style="border:0">
<tr>
<td>
<b>Klassenname </b>
</td>
<td>
<b>Geworfen
von der
Methode
</b>
</td>
<td>
<b>Bedeutung </b>
</td>
</tr>
<tr>
<td>
bad_alloc
</td>
<td>
new
</td>
<td>
Speicherzuweisungsfehler
</td>
</tr>
<tr>
<td>
bad_cast
</td>
<td>
dynamic_cast
</td>
<td>
Typumwandlungsfehler
</td>
</tr>
<tr>
<td>
bad_typeid
</td>
<td>
typeid
</td>
<td>
Falscher Objekttyp
</td>
</tr>
<tr>
<td>
out_of_range
</td>
<td>
at()
</td>
<td>
Bereichsüberschreitung in
Funktionen der C++
Standard-Bibliothek
</td>
</tr>
</table>""
""⇒"" Demo 5. Fehlerklasse bad_alloc
Als letzter catch- Block kann ein so genannter genereller Exception-Handler definiert werden.
Er übernimmt alle ausgelösten Exceptions, welche von keinem vorherigen Block übernommen werden.
catch(…)
{ //Handler für jede Art von Exceptoin
//drei Punkte statt Typ
Kann im Programm kein Handler gefunden werden, so wird das Programm beendet.
""⇒"" Demo 3. Handler-Suche
""⇒"" Demo 4. Erfolglose Handler-Suche
===Anordnung von try-Blöcken===
In einem Programm können mehrere try-Blöcke mit entsprechenden Exception-Handlern eingesetzt werden. Die Blöcke können sequentiell oder verschachtelt angeordnet werden.
**Handler-Suche in verschachtelten Blöcken**
1) Einige Exceptions können durch die Handler eines inneren try-Blocks separat behandelt werden.
2) Alle übrigen Exceptions suchen nach dem passenden Handler des äußeren try-Blocks.
===Wiederauswerfen von Exception===
Eine im inneren try-Block ausgelöste Exception kann an den umgebenen try- Block weitergereicht werden.
Die aktuell bearbeitete Exception wird nochmals ausgeworfen, um vom Handler des umgebenden Blocks
weiter bearbeitet zu werden.
{{image class="center" url="oop14.gif" width="350"}}
===Exception- Spezifikation===
Die Exceptions, die von einer Funktion ausgelöst werden kann, gehören zu den Eigenschaften einer Funktion. Sie müssen dem Anwender bekannt sein, damit geeignete Reaktionen programmiert werden können.
An die Funktions-Deklaration (Prototyp) wird einer so genannten Exception- Spezifikation angehängt.
**Deklaration**:
float pf(float y, float x) throw (DiviNull, Unterlauf);
**Definition**:
float pf(float y, float x) throw (DiviNull, Unterlauf){...}
Ist die Exception-Liste leer, so wird keine Exception zugelassen.
**Deklaration**:
float pf(float y, float x) throw ( );
**Definition**:
float pf(float y, float x) throw ( ){...}
Ist keine Exception- Spezifikation angegeben, so sind alle Exceptions zulässig.
===Standard-Fehlerklassen===
In ""C++"" wird eine Reihe von Standard-Fehlerklassen definiert.
**Einige Klassen: **
""<table class="data" width="80%" style="border:0">
<tr>
<td>
<b>Klassenname </b>
</td>
<td>
<b>Geworfen
von der
Methode
</b>
</td>
<td>
<b>Bedeutung </b>
</td>
</tr>
<tr>
<td>
bad_alloc
</td>
<td>
new
</td>
<td>
Speicherzuweisungsfehler
</td>
</tr>
<tr>
<td>
bad_cast
</td>
<td>
dynamic_cast
</td>
<td>
Typumwandlungsfehler
</td>
</tr>
<tr>
<td>
bad_typeid
</td>
<td>
typeid
</td>
<td>
Falscher Objekttyp
</td>
</tr>
<tr>
<td>
out_of_range
</td>
<td>
at()
</td>
<td>
Bereichsüberschreitung in
Funktionen der C++
Standard-Bibliothek
</td>
</tr>
</table>""
""⇒"" Demo 5. Fehlerklasse bad_alloc
Additions:
===Registrierung von Exceptions===
Jede Exception wird von einem Handler übernommen, wenn sie vorher in einem try-Block registriert wird.
Direkt bei Eintritt in ihren Handler wird eine Exception als behandelt betrachtet.
Dieses Programm erzeugt keine Endlosschleife:
void f()
{ try { throw ( 5 );}
catch(int ) { throw ( 6 ); }
}
=====3.3. Details =====
===Unterscheidung von Exceptions ===
Man kann unterschiedliche Fehlersituationen durch unterschiedliche Werte des Fehlerobjektes darstellen.
**Beispiel **
try
{ ...; if(dies) throw(7);
...; if(jenes) throw(12);
...; if(sonstwas) throw(25);
}
catch(int i)
{ switch(i)
{ case 7: ...; break; //dies
case 12: ...; break; //jenes
case 25: ...; break; //sonstwas
}
}
===Fehlerklassen===
Normaleweise werden für verschiedene Fehler eigene Fehlerklassen definiert. Ein Objekt von Fehlerklasse kann genauere Informationen über die Fehlerursache enthalten.
**Beispiel **
class Error
{ //Infos über Fehlerursache
};
void f1()
{
if( ?? )
{ Error e1;
//Infos über Fehlerursache in e1 speichern
throw (e1);
}
} %%
===Handler-Suche===
1) Jedem try-Block können mehrere catch- Blöcke (Exception-Handlers) zugeordnet werden.
2) Beim Rückzug aus Fehlersituation wird ein passender Handler gesucht, und zwar sequentiell, beginnend mit dem ersten catch-Block.
3) Es wird der erste Handler ausgeführt, dem das ausgeworfene Fehlerobjekt wie bei einem gewöhnlichen Aufruf übergeben werden kann (exception matching).
Vorsicht: throw ist kein Aufruf.
Jede Exception wird von einem Handler übernommen, wenn sie vorher in einem try-Block registriert wird.
Direkt bei Eintritt in ihren Handler wird eine Exception als behandelt betrachtet.
Dieses Programm erzeugt keine Endlosschleife:
void f()
{ try { throw ( 5 );}
catch(int ) { throw ( 6 ); }
}
=====3.3. Details =====
===Unterscheidung von Exceptions ===
Man kann unterschiedliche Fehlersituationen durch unterschiedliche Werte des Fehlerobjektes darstellen.
**Beispiel **
try
{ ...; if(dies) throw(7);
...; if(jenes) throw(12);
...; if(sonstwas) throw(25);
}
catch(int i)
{ switch(i)
{ case 7: ...; break; //dies
case 12: ...; break; //jenes
case 25: ...; break; //sonstwas
}
}
===Fehlerklassen===
Normaleweise werden für verschiedene Fehler eigene Fehlerklassen definiert. Ein Objekt von Fehlerklasse kann genauere Informationen über die Fehlerursache enthalten.
**Beispiel **
class Error
{ //Infos über Fehlerursache
};
void f1()
{
if( ?? )
{ Error e1;
//Infos über Fehlerursache in e1 speichern
throw (e1);
}
} %%
===Handler-Suche===
1) Jedem try-Block können mehrere catch- Blöcke (Exception-Handlers) zugeordnet werden.
2) Beim Rückzug aus Fehlersituation wird ein passender Handler gesucht, und zwar sequentiell, beginnend mit dem ersten catch-Block.
3) Es wird der erste Handler ausgeführt, dem das ausgeworfene Fehlerobjekt wie bei einem gewöhnlichen Aufruf übergeben werden kann (exception matching).
Vorsicht: throw ist kein Aufruf.
Additions:
{{image class="center" url="oop13.gif" width="550"}}
===Auslösen und Auffangen von Exceptions===
Die throw- Anweisung wird in folgenden Schritten ausgeführt:
1) **Fehlerobjekt auswerfen**
Vom Parameter der throw- Anweisung wird eine Kopie gemacht und im Heap gespeichert.
2) **Stack- Abwicklung**
Die Veränderungen des Stacks, die seit dem Eintritt in den try-Block stattgefunden haben, werden rückgängig gemacht. Für alle zerstörten Objekte werden Destruktoren aufgerufen.
Vorsicht: throw ist kein goto.
3) **Rückzug aus einer Fehlersituation**
Ein passender catch-Block wird gefunden und ausgeführt. Das Fehlerobjekt wird als Argument übergeben.
4) **Fehlerobjekt löschen**
Beim Verlassen des catch- Blocks wird das Fehlerobjekt im Heap gelöscht.
5) **Fortsetzung des Programms**
""⇒"" Demo 2. Stack-Abwicklung
===Auslösen und Auffangen von Exceptions===
Die throw- Anweisung wird in folgenden Schritten ausgeführt:
1) **Fehlerobjekt auswerfen**
Vom Parameter der throw- Anweisung wird eine Kopie gemacht und im Heap gespeichert.
2) **Stack- Abwicklung**
Die Veränderungen des Stacks, die seit dem Eintritt in den try-Block stattgefunden haben, werden rückgängig gemacht. Für alle zerstörten Objekte werden Destruktoren aufgerufen.
Vorsicht: throw ist kein goto.
3) **Rückzug aus einer Fehlersituation**
Ein passender catch-Block wird gefunden und ausgeführt. Das Fehlerobjekt wird als Argument übergeben.
4) **Fehlerobjekt löschen**
Beim Verlassen des catch- Blocks wird das Fehlerobjekt im Heap gelöscht.
5) **Fortsetzung des Programms**
""⇒"" Demo 2. Stack-Abwicklung
Deletions:
Additions:
{{files}}
===Rückzugsvarianten ===
===Rückzugsvarianten ===
Additions:
=====3.2. Grundbegriffe=====
===Exception-Konzept===
Eine Exception (Ausnahme) ist eine Kontrollstruktur, welche den Übergang (Sprung) von der Umgebung der Fehlersituation zur Aufrufumgebung erfüllt.
**Vorteile**:
1) Konzept beruht auf der Trennung des normalen Programmablaufs und der Behandlung von Fehlersituationen.
2) Fehlersituationen werden in der Aufrufumgebung behandelt. Die Fehlersituationen können zentral behandelt werden.
3) Das Programmverhalten wird überschaubar und sicherer.
**Anmerkung**: Durch eine Exception kann auch eine Fehlersituation bezeichnet werden.
===Schlüsselwörter try, catch, throw===
Die Ausnahmebehandlung lässt sich wie folgt skizzieren:
1) Eine Funktion versucht (""<span style="color:blue;">try</span>"") die Erledigung einer Aufgabe.
2) Wenn diese Funktion eine Fehlersituation feststellt, die sie nicht beheben kann, wird ein Ausnahmeobjekt (Exception-Objekt, Fehlerobjekt) ausgeworfen (""<span style="color:blue;">throw</span>"") bzw. wird eine Ausnahme (Exception) ausgelöst.
3) Dieses Ausnahmeobjekt wird von einer Ausnahmebehandlungsroutine (Exception-Handler) aufgefangen (""<span style="color:blue;">catch</span>""), die die Fehlersituation bearbeitet.
===Exception-Konzept===
Eine Exception (Ausnahme) ist eine Kontrollstruktur, welche den Übergang (Sprung) von der Umgebung der Fehlersituation zur Aufrufumgebung erfüllt.
**Vorteile**:
1) Konzept beruht auf der Trennung des normalen Programmablaufs und der Behandlung von Fehlersituationen.
2) Fehlersituationen werden in der Aufrufumgebung behandelt. Die Fehlersituationen können zentral behandelt werden.
3) Das Programmverhalten wird überschaubar und sicherer.
**Anmerkung**: Durch eine Exception kann auch eine Fehlersituation bezeichnet werden.
===Schlüsselwörter try, catch, throw===
Die Ausnahmebehandlung lässt sich wie folgt skizzieren:
1) Eine Funktion versucht (""<span style="color:blue;">try</span>"") die Erledigung einer Aufgabe.
2) Wenn diese Funktion eine Fehlersituation feststellt, die sie nicht beheben kann, wird ein Ausnahmeobjekt (Exception-Objekt, Fehlerobjekt) ausgeworfen (""<span style="color:blue;">throw</span>"") bzw. wird eine Ausnahme (Exception) ausgelöst.
3) Dieses Ausnahmeobjekt wird von einer Ausnahmebehandlungsroutine (Exception-Handler) aufgefangen (""<span style="color:blue;">catch</span>""), die die Fehlersituation bearbeitet.
Additions:
===Mögliche Fehlerursachen===
1) Division durch Null,
2) zu große oder zu kleine Werte für einen Datentyp,
3) kein dynamischer Speicher mehr verfügbar,
4) Fehler beim Dateizugriff, z.B. Datei nicht vorhanden,
5) ungültige Adresse im Hauptspeicher,
6) fehlerhafte Eingaben durch den Benutzer,
7) Bereichsüberschreitung eines Arrays.
===Fehlersituation===
Eine Fehlersituation ist ein Verstoß gegen die Spezifikation der Operation. Wenn die Aufgabe der Operation nicht erfüllt ist, ist es meist sinnlos, weitere Anweisungen auszuführen.
Wegen der aufgetretenen Fehlersituation muss die normale Ausführungsreihenfolge unterbrochen werden, um die Fehlersituation zu behandeln.
**Beispiel**:
%%(cpp)
if(b==0)
{ //Die Fehlersituation ist ermittelt.
//Die normale Ausführungsreihenfolge muss
//unterbrochen werden.
//Ohne Behandlung tritt der Fehler auf.
}
c = a / b ;
%%
===Erkennung und Behandlung von Fehler===
1) Der Autor einer Bibliothek kann Fehlersituation erkennen, aber er weiß nicht, wie er sie behandeln soll.
Die __Umgebung der Fehlersituation__ ist eine Stelle im Programm, wo die Fehlersituation entsteht.
2) Der Anwender einer Bibliothek weiß, wie er die Fehlersituation behandeln kann, hat aber keine Möglichkeit sie
zu entdecken.
Die __Aufrufumgebung __ist eine Stelle im Programm, wo die Fehlersituation behandelt werden kann.
**Begriffsdiskussion**: Fehlersituationsbehandlung und Fehlerbehandlung
===Traditionelle Fehlerbehandlung. Fehlernummer===
1) Meldungsausgabe und Programmabbruch, z.B. exit(-2);
2) Übergabe der Fehlernummer an den Aufrufer.
Die Nummer gibt Auskunft über Erfolg oder Misserfolg der Funktionsausführung und kann
- als Parameter,
- als Rückgabewert oder
- mittels globaler Variable
zurückgeliefert werden.
3) Fehlerbehebung, z.B. durch Wiederholung der Eingabe
Demo 1. Fehlernummer
===Traditionelle Behandlung. Nachteile===
1) Jeder Programmierer entwickelt eigene Regeln für den Umgang mit Fehlersituationen.
Ein Beispiel ist die C-Funktion getchar(), die ein Zeichen liest und zurückliefert. Damit neben jedem beliebigen Zeichen auch ein Fehlerwert zurückgeliefert werden kann, ist der Typ des Rückgabewertes nicht char, sondern int.
2) Nach jedem Aufruf müssen die Fehlerabfragen durchgeführt werden. Dadurch wird das Programm beträchtlich aufgeblasen.
1) Division durch Null,
2) zu große oder zu kleine Werte für einen Datentyp,
3) kein dynamischer Speicher mehr verfügbar,
4) Fehler beim Dateizugriff, z.B. Datei nicht vorhanden,
5) ungültige Adresse im Hauptspeicher,
6) fehlerhafte Eingaben durch den Benutzer,
7) Bereichsüberschreitung eines Arrays.
===Fehlersituation===
Eine Fehlersituation ist ein Verstoß gegen die Spezifikation der Operation. Wenn die Aufgabe der Operation nicht erfüllt ist, ist es meist sinnlos, weitere Anweisungen auszuführen.
Wegen der aufgetretenen Fehlersituation muss die normale Ausführungsreihenfolge unterbrochen werden, um die Fehlersituation zu behandeln.
**Beispiel**:
%%(cpp)
if(b==0)
{ //Die Fehlersituation ist ermittelt.
//Die normale Ausführungsreihenfolge muss
//unterbrochen werden.
//Ohne Behandlung tritt der Fehler auf.
}
c = a / b ;
%%
===Erkennung und Behandlung von Fehler===
1) Der Autor einer Bibliothek kann Fehlersituation erkennen, aber er weiß nicht, wie er sie behandeln soll.
Die __Umgebung der Fehlersituation__ ist eine Stelle im Programm, wo die Fehlersituation entsteht.
2) Der Anwender einer Bibliothek weiß, wie er die Fehlersituation behandeln kann, hat aber keine Möglichkeit sie
zu entdecken.
Die __Aufrufumgebung __ist eine Stelle im Programm, wo die Fehlersituation behandelt werden kann.
**Begriffsdiskussion**: Fehlersituationsbehandlung und Fehlerbehandlung
===Traditionelle Fehlerbehandlung. Fehlernummer===
1) Meldungsausgabe und Programmabbruch, z.B. exit(-2);
2) Übergabe der Fehlernummer an den Aufrufer.
Die Nummer gibt Auskunft über Erfolg oder Misserfolg der Funktionsausführung und kann
- als Parameter,
- als Rückgabewert oder
- mittels globaler Variable
zurückgeliefert werden.
3) Fehlerbehebung, z.B. durch Wiederholung der Eingabe
Demo 1. Fehlernummer
===Traditionelle Behandlung. Nachteile===
1) Jeder Programmierer entwickelt eigene Regeln für den Umgang mit Fehlersituationen.
Ein Beispiel ist die C-Funktion getchar(), die ein Zeichen liest und zurückliefert. Damit neben jedem beliebigen Zeichen auch ein Fehlerwert zurückgeliefert werden kann, ist der Typ des Rückgabewertes nicht char, sondern int.
2) Nach jedem Aufruf müssen die Fehlerabfragen durchgeführt werden. Dadurch wird das Programm beträchtlich aufgeblasen.