exception-safe problem
-
Gibts für das was ich vor habe irgendein Pattern? Eine Richtlinie? Erstmal zum Vorhaben:
Ich schreibe mir gerade einen Mini-ODBC-Wrapper um meine Schulübungen einfacher erledigen zu können. Folgender Mini-Auszug:
class Connection { public: Query* query (TCHAR* sql) { return new Query(hdbc,sql); } }; class Query { public: Query (HDBC hdbc, TCHAR* sql) { allocate things } ~Query () { free things } };Warum die Sache mit dem new werdet ihr euch fragen. Nun, ich will, dass die Methode Connection::query() ein Query-Objekt zurückgibt. Per Value funktioniert nicht weil sonst Query im Destruktor das HSTMT-Handle schließt (lokale Objekte sterben ja bekanntermaßen).
Also mache ich new und lasse den User per Release() das objekt zu späterem Zeitpunkt wieder freigeben. Bzw. erstmal mit delete.
Noch kein Problem in Sicht. Doch will ich Fehlerbehandlung nun mit Exceptions einbauen:
try { Connection* conn = manager->connect(dsn,uid,pwd); // arbeite mit conn delete conn; // oder eben release, etc. } catch(Exception& e) { // fehler }Problem: Im Falle einer Exception wird das Objekt nicht mehr gelöscht. Was also tun?
Anderes Problem: Auch in Destruktoren können Fehler auftreten: Was nun tun? Einfach ignorieren?

MfG SideWinder
-
SideWinder schrieb:
Problem: Im Falle einer Exception wird das Objekt nicht mehr gelöscht. Was also tun?
Smart-Ptr?
Anderes Problem: Auch in Destruktoren können Fehler auftreten: Was nun tun? Einfach ignorieren?
Weißt du nicht wie du verfahren sollst wenn ein Dtor aufgrund einer Exception aufgerufen wird und dieser Dtor ebenfalls Exceptions werfen könnte?
Wenn ja: Ich würde es so machen: (Wobei ich mir nicht ganz sicher bin ob das legal ist
ist rein aus dem Bauch heraus...)class foo { public: ~foo() { try { // destruieren. } catch(dtor_error& err) { if(uncaught_exception()) // Dtor wurde aufgrund einer Exception aufgerufen // UND eine exception ist zusätzlich in selbigem aufgetreten else // Exception ist nur im Dtor geworfen worden. } } };Gruß Caipi
-
SideWinder schrieb:
Problem: Im Falle einer Exception wird das Objekt nicht mehr gelöscht. Was also tun?
Bringt dich auto_ptr weiter?
try { std::auto_ptr<Connection> conn(manager->connect(dsn,uid,pwd)); // arbeite mit conn } catch(Exception& e) { // fehler }SideWinder schrieb:
Anderes Problem: Auch in Destruktoren können Fehler auftreten: Was nun tun? Einfach ignorieren?
Was heißt denn "können Fehler auftreten"? Zwangsläufig Exceptions? Wenn ja, musst du die propagieren oder kannst du sie im Dtor behandeln?
-
Destruktoren sollten niemals Exceptions werfen dürfen, weil sonst niemals Exceptionsicherheit garantiert werden kann!
Nachzulesen in "Exceptional C++" von Herb Sutter.
-
-> Also ich verwende jetzt auto_ptr, der reicht mir.
-> In Destruktoren werden Fehler nun ignoriert. Sollte etwas wie SQLFreeHandle() jemals fehlschlagen ist sowieso das Programm ebreits abschussreif.Danke an alle

Anmerkung: C++ fehlt das finally-Schlüsselwort aus Java.
MfG SideWinder
-
Das ist Pflichtlektüre für solche Sachen: http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/
-
SideWinder schrieb:
Anmerkung: C++ fehlt das finally-Schlüsselwort aus Java.
Nö. C++ verfolgt einfach einen anderen Ansatz. Man verwendet RAII und verzichtet größten Teils auf try-catch-Blöcke (und damit auch auf finally). Ob man das jetzt elleganter findet oder nicht, sei dahin gestellt. Fakt ist, dass
eins von beiden reicht um Duplikation zu verhindern.
-
Das ist Pflichtlektüre für solche Sachen: http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/
Thx, werd mir das auch mal bei Gelegenheit reinziehen.
-
Hat das CUJ ein Problem mit Opera? Die Seite zeigt im Opera nichts an

Ob man das jetzt elleganter findet oder nicht,...
...hängt wohl auch damit zusammen was man in letzter Zeit benützt hat *g*
Danke nochmal

MfG SideWinder
-
Die Seite zeigt im Opera nichts an
Bei mir genauso.
Dafür hab ich meinem Opera so einen schönen "Mit IE öffnen" Button zugelegt