[Hallo Liste, ich habe mich inzwischen in meinem schlauen Buch (2. Auflage von BjarneStroustrup) schlau gemacht. Hier das Ergebnis unter besonderer Berücksichtigung der Bedenken von Helmut (und auch meiner eigenen): --rae]
nicht freigegebene Resorcen |
|
Dann kann in einer Funktion 'useFile()' die Resource FILE auch nach einer Exception automatisch wieder freigegeben werden, da sich die Klasse auf dem lokalen Stack befindet und daher am Ende der Funktion oder bei dem Passieren der Funktion durch eine Exception automatisch wieder freigegeben wird.
|
Memory-Leaks |
Das gleiche kann man mit Speicher machen, der dynamisch angefordert wird, solange er nur in der anfordernden Funktion selbst benutzt wird. Soll der angeforderte Speicherblock z.B. als Ergebnis an die rufende Funktion uebergeben werden, so muss die Funktion, die den Speicher allokiert, alle Exceptions auffangen und zumindest den Speicher wieder frei geben. Kann die Funktion die Exception(s) nicht abschliessend behandeln, so kann sie die Exception ihrerseits danach wieder weiterwerfen.
Zwei-Phasen-Konzept |
Bei Zustandsveränderungen von bestehenden Objekten muss aber trotzdem ein 2-Phasen-Konzept eingehalten werden, wenn die Zustandsveränderung (z.B. Zuweisung) Exception-sicher sein soll: Zuerst müssen alle "neu benötigten" Resourcen an initialisierte Objekte gebunden werden, dann erst darf die eigentliche Zustandsänderung beginnen.
Wer das 2-Phasen-Sperrkonzept zur Sequentialisierung von Transaktionen kennt, kann eine Zustandsänderung als Transaktion auffassen und muss nichts neues dazulernen. Erst wenn alle "Sperren" erfolgreich gesetzt sind, darf eine davon auch genutzt werden.
Undifferenzierte Rueckgabewerte bei Exceptions |
Man kann Ausnahmen auch einen Wert mitgeben:
|
Meines Wissens kann man dieses Verfahren nicht 1:1 auf Java umsetzen, da dort Objekte nie am Stack angelegt werden (dort liegt immer nur eine Referenz) und weil die Freigabe von Objekten an die GarbageCollection gebunden, also dem Zufall überlassen ist. Der Weg, den man in Java gehen muss, ist der über explizite "finalize"-Funktionsteile in jeder resourcenverwendenden Funktion. Ist das korrekt, oder habe ich da etwas falsch verstanden? -- HelmutLeitner