Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure II Prof. Dr. Gisbert Dittrich
20-2 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Gliederung Ausnahmebehandlung Grundphänomene – Am Beispiel Konto: 3 Varianten Möglichkeiten bei der Verwendung von Klassenobjekten – 4 Varianten
20-3 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Beispiel: Kontoführung Ich kann ein Konto eröffnen, auf ein Konto einzahlen, von einem Konto abheben, ein Konto überziehen, ein Konto wieder schließen. (Abstrakter Datentyp)
20-4 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Klasse EinfachesKonto class Konto { protected: int stand; public: Konto(){stand = 0;} ~Konto(){ cout << "Nachricht" << endl; } void Einzahlen(int k) {stand += k;} int Abheben(int k) { stand -= k; return k; } int KontoStand() {return stand;} };
20-5 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Klasse EinfachesKonto (Forts.) int main() { int i, j, st; Konto * kto = new Konto; for (i = 0; i < 5; i++) { j = rand(); cout << "\nEingezahlt: \t" << j; kto ->Einzahlen(j); cout << ",\tAbgehoben:\t" Abheben((i+1)*rand()); st = kto ->KontoStand(); cout << ",\tKontostand:\t" << st << (st < 0? " *": ""); } kto ->~Konto(); } Konto1
20-6 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Klasse EinfachesKonto (Forts.) Eingezahlt: 16838, Abgehoben: 5758, Kontostand: Eingezahlt: 10113, Abgehoben: 35030, Kontostand: * Eingezahlt: 31051, Abgehoben: 16881, Kontostand: 333 Eingezahlt: 23010, Abgehoben: 29676, Kontostand: * Eingezahlt: 16212, Abgehoben: 20430, Kontostand: * Konto bei Geschaeftsschluss aufgeloest
20-7 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Überziehung des Kontos Wie wird das behandelt? Annahme: – Die Überziehung hat Konsequenzen: – Konto wird dann aufgelöst. Möglichkeiten: nach jeder Abhebung wird gefragt, ob das Konto überzogen ist, – ja: Konto auflösen, Abbruch – nein: weitermachen wie gewohnt.
20-8 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Überziehung des Kontos ist für den Code umständlich: – Der Normalfall und der Ausnahmefall werden ineinander vermischt behandelt Alternative: Ausnahmebehandlung – Wenn die Ausnahmesituation entsteht, wird dem benutzen-den Programmteil gesagt: Hier stimmt etwas nicht, es muß etwas geschehen d.h. Ausnahmebehandlung
20-9 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Modifikation der Klasse class Konto { protected: int stand; public: Konto(){stand = 0;} ~Konto(){cout << "Nachricht";} void Einzahlen(int k) {stand += k;} int Abheben(int k) {stand -= k; if (stand < 0) throw k; return k; } int KontoStand() {return stand;} };
20-10 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Interpretation Wenn diese Bedingung stand < 0 erfüllt ist, aktiviere eine Ausnahme mit dem Wert k: (das ist der Betrag, bei dessen Abheben das Konto überzogen wurde) Die Ausnahme muß irgendwo behandelt werden: (d.h. zum throw gehört ein catch )
20-11 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung... der Fänger Konto * kto = new Konto; try{ for (i = 0; i < 5; i++) { cout << "\nEingezahlt: \t" <<...; kto->Einzahlen(...); abh = kto->Abheben(...); cout << ",\nabgehoben: \t" << abh; st = kto->KontoStand(); cout << ",\tKontostand:\t" << st << (st < 0? " *": ""); } catch(int t) { cout << "\nKonto ueberzogen.." << t << "DM\n"; kto->~Konto(); } Konto * kto = new Konto; for (i = 0; i < 5; i++) { cout << "\nEingezahlt: \t" <<...; kto->Einzahlen(...); abh = kto->Abheben(...); cout << ",\nabgehoben: \t" << abh; st = kto->KontoStand(); cout << ",\tKontostand:\t" << st << (st < 0? " *": ""); } Programm
20-12 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Hier wurde die Ausnahme offenbar ausgelöst Ausgabe Eingezahlt: 16838, abgehoben: 5758, Kontostand: Eingezahlt: Konto ueberzogen beim Abheben von DM Konto aufgeloest
20-13 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Anmerkungen Der Aufruf einer Methode, die eine Ausnahme auslöst, muß in einem Block stattfinden, der mit try eingeleitet wird, also: try {... Methode oder Funktion, die eine Ausnahme auslöst... }
20-14 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Anmerkungen Unmittelbar auf try folgt ein oder folgen mehrere catch zur Behandlung der Ausnahme: catch ist parametrisiert: Der formale Parameter wird beim Behandeln der Ausnahme durch einen aktuellen Parameter ersetzt, der von throw gesetzt wird. Analogie: – Funktionsvereinbarung: Arbeit mit formalen Parametern – Funktionsaufruf: Substitution durch aktuelle Parameter
20-15 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Kontrollfluß bei der Aktivierung einer Ausnahme: Aktivieren der Ausnahme mit throw Suchen der passenden catch -Klausel Ausführen des entsprechenden Blocks (mit Wurf- Geschoß als aktuellem Parameter) Danach Verlassen der catch -Klausel und Weiterar- beit mit dem Block, der unmittelbar auf die catch - Klauseln folgt Insbesondere: Keine Rückkehr in den try -Block oder die aktivierende Prozedur Anmerkungen
20-16 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Beispiel (Forts.) Verdacht auf Steuerbetrug, wenn ein zu hoher Betrag eingezahlt wird. --> Aktivierung einer Ausnahme. Jedoch Problem: Kann die Ausnahme nicht mit throw k aktivieren, da die beiden Situationen auf diese Art nicht voneinander getrennt werden können. Es gilt aber: Es können Instanzen beliebiger Klassen geworfen werden.
20-17 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Beispiel (Forts.) Definiere zwei Klassen Ueberziehung VerdachtSteuerbetrug Wirf entsprechende Ausnahmen Behandle die Ausnahmen nach den Typen der geworfenen Argumente, also: Ueberziehung könnte anders behandelt werden als VerdachtSteuerbetrug – z. B.: bei Ueberziehung schließen wir das Konto
20-18 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung noch eine ganz normale Klasse Modifiziertes Konto class Ueberziehung { public: int wert; Ueberziehung(int j) { wert = j; } }; class VerdachtSteuerbetrug { public: int wert; VerdachtSteuerbetrug(int z) { wert = z; } }; eine ganz normale Klasse
20-19 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung hier werden die entsprechenden Instanzen geworfen Modifiziertes Konto (Forts.) void Einzahlen(int k) { stand += k; if (k > 30000) throw new VerdachtSteuerbetrug(k); } int Abheben(int k) { stand -= k; if (stand < 0) throw new Ueberziehung(k); return k; }
20-20 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Behandlung der Ausnahmen catch(Ueberziehung * t) { cout << "\nKonto ueberzogen beim Abheben von " wert << " DM\n"; kto->~Konto(); } catch (VerdachtSteuerbetrug * r) { cout << "\nZu hohe Einzahlung. Steuerbetrug? " wert << endl; } Konto3.cppProgramm
20-21 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Ausgaben Zweite Einzahlung: Eingezahlt: 17000, Abgehoben: 16838, Kontostand: 162 Eingezahlt: Zu hohe Einzahlung. Steuerbetrug? > Hier sind alle Ausnahmen behandelt <-- Zweite Einzahlung: Eingezahlt: 17000, Abgehoben: 16838, Kontostand: 162 Eingezahlt: Zu hohe Einzahlung. Steuerbetrug? > Hier sind alle Ausnahmen behandelt <-- Zweite Einzahlung: 3134 Eingezahlt: 17000, Abgehoben: 16838, Kontostand: 162 Eingezahlt: 3134 Konto ueberzogen beim Abheben von 5758 DM Konto aufgeloest --> Hier sind alle Ausnahmen behandelt <--
20-22 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Passendes catch ? Identifikation der passenden Behandlung? throw T wird von catch (Klasse W) gefangen, falls gilt: – T ist vom Typ W oder der Typ von T erbt von W – diese catch -Klausel ist die erste Klausel, auf die diese Bedingung paßt.
20-23 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Beispiel: Definitionen class eins {}; class zwei: public eins {}; class drei { public: void wirfEins() { cout << "\nin wirfEins\n"; throw new eins; } void wirfZwei() { cout << "\nin wirfZwei\n"; throw new zwei; } }; Instanzen dieser Klassen sollen geworfen werden hier wird geworfen
20-24 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Klasse zwei ist Spezialfall von Klasse eins Benutzung Ausnahme1 void main() { drei * d3 = new drei; try { d3->wirfZwei(); } catch(eins *) { cout << "\nschmeiße eins\n"; } catch(zwei *) { cout << "\nschmeiße zwei\n"; } }
20-25 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung void main() { drei * d3 = new drei; try { d3->wirfZwei(); } catch(zwei *) { cout << "\nschmeiße zwei\n"; } catch(eins *) { cout << "\nschmeiße eins\n"; } Benutzung Ausnahme1A
20-26 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Diskussion Ausgabe: Ausnahme1: in wirfZwei schmeiße eins Denn: catch(eins *) fängt die Ausnahme throw (new zwei) (Regel: erste Klausel, die paßt). Ausnahme1A: in wirfZwei schmeiße zwei
20-27 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung class vier { public: drei * three; vier() { three = new drei; } void wirf() { try{ three->wirfEins(); } catch(eins *) { cout << "\n\tgefangen!\n"; throw new zwei; } } }; Weiterwerfen: Ausnahme3 Programm
20-28 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Was passiert? Ausgabe: in wirfEins gefangen! schmeiße zwei In der Klasse vier wird in der Methode wirf durch den Aufruf von three->wirfEins() eine Ausnahme vom Typ eins aktiviert. Die Ausnahme wird in der Methode wirf behandelt, indem eine Ausnahme von Typ zwei aktiviert wird, die in main behandelt wird.
20-29 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung class vier { public: drei * three; vier() { three = new drei; } void wirf() { try{ three->wirfEins(); } catch(eins *) { cout << "\n\tgefangen!\n"; throw new zwei; } }; Klasse vier: Wiederholung
20-30 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung class vierExotisch { public: drei * three; vierExotisch () { three = new drei; } void wirf() { try{ three->wirfEins(); } catch(zwei *) { cout << "\n\tgefangen!\n"; throw new zwei; } }; wirft Ausnahme vom Typ eins Klasse vier: exotisch (?)
20-31 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Was passiert? Die Ausnahme vom Typ eins wird nicht in der Methode wirf, sondern in main behandelt. Klar: Es ist kein passender Fänger in der Methode vorhanden.
20-32 Prof. Dr. G. Dittrich EINI II Kap. 20: Ausnahmebehandlung Für heute: Ende