Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

12 Ausnahmebehandlungen I

12 Ausnahmebehandlungen I

In diesem Kapitel werde ich Ihnen verraten, wie man Fehler abfangen kann, welche nicht oder nur schwer, vorherzusehen sind. Ich spreche von dem s.g. Exceptionhandling. Doch was meine ich damit, dass man Fehler schwer vorhersehen kann?

Stellen Sie sich vor, Sie arbeiten mit einer Datei auf einem USB Stick und während des Schreibens, zieht jemand den Stick aus dem Rechner. Schon haben Sie eine unvorhersehbare, aber trotzdem wahrscheinliche Fehlersituation, um die Sie sich kümmern müssen. Genau dieses Beispiel werde ich dann im nächsten Kapitel, wenn es um Dateien geht, noch einmal aufgreifen. An dieser Stelle werde ich aber nur ein paar Grundlagen diskutieren und ein paar sehr einfache Beispiele bringen.

Zum Seitenanfang
Zum Inhaltsverzeichnis

12.1 Exceptions

12.1 Exceptions

Eine Exception ist eine Ausnahme und kein Fehler! Mit ihr kann man der aufrufenden Funktion signalisieren, dass etwas schief gelaufen ist bzw. nicht stimmt. Immer dann, wenn Ihnen beim ausführen eines Programmes, die Meldung entgegen kommt "Zugriffsverletzung im Speicherbereich xy", handelt es sich nicht um einen Fehler, sondern um eine Exception, die durch die Speicherverwaltung von Windows erzeugt wurde. Klar könnte man jetzt ganz naiv sagen, dass dies doch ein Fehler ist, aber streng genommen ist es das nicht. Wäre es ein tatsächlicher Fehler, würde überhaupt keine Meldung kommen und das System sich gnadenlos aufhängen.

Eine Behandlung von Exception ist erst seit C++ möglich und intern werden auch Objekte erzeugt und umher "geschmissen". Wie Sie diese Objekte benutzen bzw. sogar selber erstellen können, werde ich allerdings erst in einem späteren Kapitel mit Ihnen besprechen, sobald ich Ihnen gezeigt habe, was ein Objekt ist und wie man mit ihm umgeht.

Zum Seitenanfang
Zum Inhaltsverzeichnis

12.3 __try und __finally

12.3 __try und __finally

In vielen anderen Sprachen, gibt es einen s.g. "try finally" Mechanismus, mit welchen man dafür sorgt, dass auch im Fehlerfall, definitiv noch Operationen ausgeführt werden, wie z.B. das nachträgliche Freigeben von Speicher. Dieser Mechanismus ist im reinen C++ Standard nicht enthalten, aber in Visual Studio hat sich Microsoft etwas einfallen lassen, um dies nachzustellen. Normalerweise braucht man diesen Mechanismus auch nicht, da im Fehlerfall sowieso der "catch" Block ausgeführt wird und es anschließend ganz normal weiter geht. Das Freigeben des Speichers könnte man also auch außerhalb des "try catch" Blockes packen. Hin und wieder wird aber trotzdem ein "try finally" gebaut, da der Quelltext so etwas besser lesbarer wird bzw. so nachdrücklich betont wird, dass aus jeden Fall noch etwas getan werden muss. Es handelt sich also nur um eine reine stilistische Angelegenheit, was erklärt, warum dieser Mechanismus nicht zum C++ Standard gehört.

Im Nachfolgenden Quelltextfragment sehen Sie, wie man ein solches Konstrukt baut.

 1
 2
 3
 4
 5
					
__try {
	// Geschützter Quelltext
} __finally {
	// Abschließende Arbeiten
} // end of try
					
Zum Seitenanfang
Zum Inhaltsverzeichnis

12.2 try und catch

12.2 try und catch

Wie Sie vielleicht an der Überschrift schon erkennen können, geht es jetzt um das Absichern von Quelltextteilen. Immer dann, wenn man um einen Quelltext "try" und "catch" herum baut, wird der darin befindliche Code, in einer Art geschützten Umgebung ausgeführt und wenn was schief läuft, wird sofort in den "catch" Abschnitt gesprungen, um dort eine entsprechende Meldung abzugeben, bzw. den Fehler weiter delegieren zu können.

Das Schema sieht so aus: try <Anweisung> catch ((<Ausnahmetyp> <Variable>)|...) <Anweisung>

Hier mal ein kleines Beispiel

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
					
try {
	int iWert = 10;

	// Von -5 bis 5
	for (int iCounter=-2; iCounter<=2; iCounter++) {
		printf("%i\n", iWert / iCounter);
	} // end of for
} catch (...) {
	printf("Geteilt durch 0 ist nicht erlaubt!\n");
} // end of try
					

Ausgabe:

-5
-10
Geteilt durch 0 ist nicht erlaubt!
		

Wie Sie sehen können, wird in der Schleife irgendwann eine Division durch 0 auftreten und dann würde das Programm abstürzen. Dies liegt daran, dass intern eine Exception ausgelöst wird, in dem Fall ein Run-Time-Error 200. Genau in diesem Fall, wird in den "catch" Block gesprungen und man kann dem Anwender auf diese Situation hinweisen.

Auffällig ist, dass ich in den Klammern des "catch" drei Punkte gesetzt habe. Normalerweise kommt hier ein Fehlertyp hin, aber wenn man nicht weiß, was alles für Fehler auftreten können bzw. nicht weiß, wie auftretende Fehler definiert sind, kann man diesen Platzhalter benutzen und allgemein reagieren. Erst wenn man den Typ kennt und angibt, kann man sich aus ihm nähere Informationen zur Fehlerursache holen. Dies werde ich aber wie erwähnt erst später behandeln.

Des Weiteren sollten Sie sehen, dass der obige Block sofort verlassen wird, falls ein Fehler auftritt und dass man nicht wieder zurückkehren kann. In meinem Beispiel bedeutet dies, dass die Ausgabe nach dem Fehler beendet wird. Deshalb sollte man genau überlegen, wo man ein "try" einbaut. Im Falle des Beispiels wäre es also besser, das Abfangen des Fehlers, innerhalb der Schleife zu machen. Aber werden Sie bitte nicht Faul. Eine Division durch 0 kann man auch im Vorfeld mit einer if Anweisung abfangen, da ein "try" um vieles langsamer ausgeführt wird. Alles was Sie also geschickt mit einer Bedingung abfangen können, sollten Sie unter allen Umständen auch so abfangen. Nur dann, wenn man absolut nicht weiß, wie man etwas mit einer Bedingung lösen kann, benutzt man es in ein "try".

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012