30.06.2013 Aufrufe

Softwareentwicklung in C++ - ASC

Softwareentwicklung in C++ - ASC

Softwareentwicklung in C++ - ASC

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

318 11. Exceptions<br />

Vorsicht Falle: Leider wird bei der Behandlung von Exceptions sehr oft<br />

e<strong>in</strong> gravierender Fehler gemacht, der zum Teil auf Schlampigkeit, zum Teil<br />

aber auch auf Unwissenheit beruht: Jede Exception, die <strong>in</strong>nerhalb e<strong>in</strong>es try<br />

Blocks auftritt, bewirkt sofort das Anspr<strong>in</strong>gen des entsprechenden catch.<br />

Das bedeutet, dass alle Statements, die unterhalb der Zeile stehen, <strong>in</strong> der die<br />

Exception aufgetreten ist, nicht mehr ausgeführt werden. Sollte dort Code<br />

stehen, der unbed<strong>in</strong>gt immer ausgeführt werden muss (z.B. irgende<strong>in</strong> delete<br />

von dynamisch allokiertem Speicher), dann hat man e<strong>in</strong> Problem, denn bis zu<br />

dieser Zeile kommt man im Falle e<strong>in</strong>er Exception ja nicht! Aus diesem Grund<br />

muss man sich sehr gut überlegen, wie man try Blöcke setzt, damit man nicht<br />

<strong>in</strong>s offene Messer läuft und e<strong>in</strong>erseits zwar e<strong>in</strong>e “schöne” Fehlerbehandlung<br />

implementiert, die aber selbst gleich noch schlimmere Fehler macht und z.B.<br />

wachsende Programme oder sonstige schlimme Inkonsistenzen verursacht!<br />

Es stellt sich nun die Frage, wie wir die Exception, die <strong>in</strong> Zeile 135 geworfen<br />

wurde, durch catch an e<strong>in</strong>er ganz anderen Stelle im Programm fangen<br />

können. Eigentlich müsste das Exception Objekt ja zu diesem Zeitpunkt<br />

schon lange tot se<strong>in</strong>, da die throw Expression, <strong>in</strong> deren Rahmen das temporäre<br />

Objekt generiert wurde, bereits fertig abgearbeitet ist.<br />

Die Antwort darauf klärt auch gleich das Phänomen der zwei erzeugten<br />

Objekte auf: Wird e<strong>in</strong>e Exception geworfen, so wird immer (!) automatisch<br />

e<strong>in</strong>e Kopie dieser Exception generiert. Genau diese Kopie ist es, die wir<br />

auch durch unser catch fangen und nicht, wie viele Entwickler annehmen,<br />

das Orig<strong>in</strong>al! Die Kopie ist ebenfalls e<strong>in</strong> temporäres Objekt und die Lifetime<br />

dieses Objekts endet, sobald der catch Block verlassen wurde, denn dort ist<br />

für den Compiler dann diese Expression zu Ende.<br />

Jetzt, wo diese Eigenheit geklärt ist, können wir den Output zu Ende<br />

analysieren:<br />

1. In Zeile 167 wird e<strong>in</strong> Aufruf auf setElementAt mit Index 5 als Parameter<br />

durchgeführt.<br />

2. In Zeile 134, <strong>in</strong> der Implementation von setElementAt, wird e<strong>in</strong>e Überprüfung<br />

vorgenommen, ob dieser Index auch wirklich zulässig ist. Weil<br />

wir aber die Instanz von Vector so angelegt haben, dass sie maximal 3<br />

Elemente halten kann, wird entschieden, dass es mit der Zulässigkeit gar<br />

nicht so weit her ist.<br />

3. Es wird also entsprechend <strong>in</strong> Zeile 135 e<strong>in</strong>e IndexOutOfBoundsException<br />

als temporäres Objekt geworfen und dadurch wird die Methode an dieser<br />

Stelle auch verlassen. Der Konstruktoraufruf des temporären Objekts<br />

äußert sich im Output durch die Meldungen<br />

default - construct<strong>in</strong>g Exception, id = 0<br />

default - construct<strong>in</strong>g IndexOutOfBoundsException, id = 0<br />

4. Wie bereits erwähnt, wird von throw sofort e<strong>in</strong>e Kopie dieses Objekts<br />

angelegt. Da wir e<strong>in</strong>en Copy Constructor bereitgestellt haben, wird die-

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!