try und finally
-
Hallo.
Ich beschäftige mich gerade mit möglich auftretende Exceptions.
standard ist ja
try { // Code der abgearbeitet werden soll } __catch(...) { // Es ist irgendein Fehler passiert }
Wie man den passenden Fehler bekommt, habe ich noch nicht ganz verstanden, aber meine Frage bezieht sich eher auf das __finally, wozu ist das gut wenn es doch immer, egal ob Fehler vorhanden, durchlaufen wird?
-
Hallo
manchmal will man eben gewisse Funktion immer bein ende Ausführen, egal ob Fehler oder nicht. Beispiel :
int Funk() { int Ergebnis; struktur* x = 0; struktur* y = 0; try { x = BaueGroßeSpeicherStruktur(); MacheEtwas(x); if (!(y=BaueAndereGroßeSpeicherStruktur())) return(-1); MacheEtwas(y); } __finally { LöscheStruktur(x); LöscheStruktur(y); } return Ergebnis; }
Dieses Beispiel ist natürlich etwas konstruiert, Das liese sich auch eleganter mit std::auto_ptr und exceptions lösen.
bis bald
akari
-
Hallo,
Standard ist übrigens das hier
try { // Code der abgearbeitet werden soll } catch(...) { // Es ist irgendein Fehler passiert }
bzw. bei catch auch
catch(exeption_type &e) { // Es ist irgendein Fehler passiert }
Wobei für exception_type der Type der zu fangende Exception oder deren Basisklassentyp angegeben werden muß.
__finally ist kein Standard (bei C++).
-
Danke euch Beiden
Aber
akari schrieb:
__finally { LöscheStruktur(x); LöscheStruktur(y); } return Ergebnis; }
wo liegt der Unterscheid zu
/* __finally { } */ LöscheStruktur(x); LöscheStruktur(y); return Ergebnis; }
?
-
Es wird nicht ausgeführt, wenn ein Fehler aufgetreten ist. Die Funktion wird dann nämlich aus dem catch-Block heraus verlassen und weder Lösche... noch return xxx wird ausgeführt.
-
Tschuldigung, aber aus dem Satz werd ich nicht wirklich schlau.
Wenn kein Fehler vorliegt geht er die __finally normal durch und den Rest des Programmes.
Wenn doch ein Fehler vorliegt geht er nur noch die __finally durch und beendet anschliessend das Programm bzw die Funktion?Das glaub ich erlich nicht, schon allein daraus das die Funktion meist einen Rückgabewert hat und durch einen undefinierten Abbruch weiteren Mist produzieren würde.
Kurz, ich habe den Satz wohl nicht verstanden. Wenn möglich bitte etwas umformulieren
-
Sorry...
der __finally-Block wird immer ausgeführt. Egal ob ein Fehler auftritt oder nicht. Wenn nur try / catch vorhanden ist und ein Fehler auftritt wird die Funktion innerhalb des catch-Blocks beendet. Alles was danach noch kommt wird nicht mehr ausgeführt.
try { // Code der abgearbeitet werden soll } catch(...) { // Es ist irgendein Fehler passiert // ohne __finally wird die Funktion hier beendet } // und das folgende somit nicht mehr ausgeführt. LöscheStruktur(x); LöscheStruktur(y); return Ergebnis; }
Ich verschachtel das Ganze meist so:
try { try { // Code der abgearbeitet werden soll } catch(...) { // Es ist irgendein Fehler passiert } } __finally { LöscheStruktur(x); LöscheStruktur(y); return Ergebnis; }
Dadurch habe ich in dem __finally-Block eine zentrale Stelle an der ich aufräumen kann und auch nur eine Stelle in der Funktion, die das 'Ergebnis' zurückliefert.
-
Irgendwie komme ich mir vor als rede ich mit Politiker
Ich meine es wird etwas schön geredet was keinerlei Zweck dient. Zumindest sehe ich hier immernoch keinen.try { try { // Code der abgearbeitet werden soll } catch(...) { // Es ist irgendein Fehler passiert } } __finally { LöscheStruktur(x); LöscheStruktur(y); return Ergebnis; }
bleibt doch immernoch nix weiter als
try { // Code der abgearbeitet werden soll } catch(...) { // Es ist irgendein Fehler passiert } LöscheStruktur(x); LöscheStruktur(y); return Ergebnis;
Ist wohl wie wenn jemand
if (var) x = 1;
oder
if (var) { x=1; }
schreibt. Ok, dann müssen wir nicht näher drauf eingehen.
-
Ok, gehen wir noch mal auf dieses Beispiel ein:
try { // Code der abgearbeitet werden soll } catch(...) { // Es ist irgendein Fehler passiert // ohne __finally wird die Funktion hier beendet } // und das folgende somit nicht mehr ausgeführt. LöscheStruktur(x); LöscheStruktur(y); return Ergebnis; }
Wenn im try-Block ein Fehler auftritt, wird der catch-Block aufgerufen und die Funtktion danach beendet. Das heißt LöscheStruktur(x), LöscheStruktur(y) und return Ergebnis werden niemals ausgeführt! Das wiederum bedeutet, dass der Rückgabewert undefiniert ist und Speicherlecks bleiben.
Normalerweise hat man auch mehr als einen try-catch-Block innnerhalb eines try-finally-Blockes. Somit kann man die ganzen Aufräumarbeiten und die Werterückgabe im __finally-Block durchführen, anstatt sie in jedem catch-Block einzeln angeben zu mössen. Das macht den Code leserlicher und wartbarer.
-
Torsten.001 schrieb:
Irgendwie komme ich mir vor als rede ich mit Politiker.
Noch so eine Beleidigung und das war die letzte Antwort von mir.
-
Joe_M. schrieb:
Wenn im try-Block ein Fehler auftritt, wird der catch-Block aufgerufen und die Funtktion danach beendet.
Nicht unbedingt. Wenn die Exception im catch-Block nicht weitergereicht wird und der Fehler dort ordnungsgemäß behandelt wird, geht es nach dem catch-Block in der Funktion durchaus weiter wenn kein weiters äußeres try vorhanden ist.
-
Braunstein schrieb:
Nicht unbedingt. Wenn die Exception im catch-Block nicht weitergereicht wird und der Fehler dort ordnungsgemäß behandelt wird, geht es nach dem catch-Block in der Funktion durchaus weiter wenn kein weiters äußeres try vorhanden ist.
Definiere 'ordnungsgemäß behandelt'. Ich habe, insbesondere bei Datenbankzugriffen, die einen Fehler verursachen, Probleme Code hinter dem catch (EDatabaseError &ErrObject) auszuführen...
-
Normalerweise sollte es reichen die Exception mit throw nicht weiterzugeben. Bei mir hat das eigentlich meistens auch funktioniert (bei EConvertError auf jeden Fall).
Es kann da natürlich Ausnahmen geben. Man müsste vielleicht mal einen entsprechenden Test mit verschiedenen Exceptions machen.
-
Braunstein schrieb:
Es kann da natürlich Ausnahmen geben. Man müsste vielleicht mal einen entsprechenden Test mit verschiedenen Exceptions machen.
Ja, das müßte man. Da es aber doch eine ganze Menge möglicher Exceptions gibt, ist das recht aufwendig...
Deswegen umgehe ich das Problem mit einem try __finally-Block um die try-catch-Blöcke. Das was im __finally-Abschnitt steht, wird grundsätzlich ausgeführt. Problem gelöst.