Ich habe eine Klasse, die RAII zur Bereinigung verwendet, falls etwas schief geht. Das bedeutet, dass die Klasse ein Flag enthält, das angibt, ob die Arbeit abgeschlossen wurde. Wenn dieses Flag beim Aufruf des Konstruktors nicht gesetzt ist, führt es seine Bereinigungsaufgaben aus und erstellt Protokollmeldungen. Nun möchte ich, dass diese Klasse einen Schritt schlauer wird, dh sie sollte herausfinden, ob der Fehler passiert ist, weil die Arbeit abgebrochen wurde (dh eine Ausnahme wurde ausgelöst und der Destruktor aufgerufen) oder weil jemand diese Klasse missbraucht hat und niemals tatsächlich beendete die Arbeit. Das bedeutet, dass ich im Destruktor herausfinden müsste, ob eine Ausnahme aktiv ist. Wenn einer gefunden wird, würde ich eine Protokollnachricht erzeugen, die möglicherweise den Inhalt der Ausnahme druckt und dann erneut ausgibt. Ich vermute etwas wie das.
%Vor% Ich bin mir jedoch nicht sicher, ob das überhaupt funktionieren würde, da die Ausnahme bereits vor dem Aufruf des Destruktors aktiv ist und nicht aus dem try
-Block stammt. Auch ich benutze throw;
innerhalb des Destruktors und eine Ausnahme an dieser Stelle zu werfen ist eine wirklich schlechte Idee. Also würde ich es nicht tun, außer der Standard garantiert klar, dass dieser Fall eine Ausnahme (kein Wortspiel beabsichtigt) zu dieser Regel (die ich nicht kenne).
Also ist das überhaupt möglich, oder sollte ich mit dieser Situation anders umgehen?
Sie können std::uncaught_exception()
verwenden, das true zurückgibt, wenn eine Ausnahme ausgelöst wurde, aber ein catch
hat es noch nicht behandelt. Sie können diese Überprüfung in Ihrem Destruktor verwenden, um Entscheidungen darüber zu treffen, was dies tun soll oder nicht.
Vorsicht: Gute Programmierungsrichtlinien schreiben normalerweise vor, dass sich der Destruktor unter verschiedenen Umständen signifikant anders verhalten sollte. Verwenden Sie diese Funktion, aber missbrauchen Sie sie nicht. Eine häufige Verwendung ist ein Destruktor, der nur auslöst, wenn es keine aktive nicht abgefangene Ausnahme gibt (diese Funktion gibt false zurück). Aber diese Art von Verhalten ist im Allgemeinen kein gutes Design. Wenn die Bedingung schlimm genug war, um eine Ausnahme zu rechtfertigen, sollte sie wahrscheinlich nicht ignoriert werden. Destruktoren sollten sowieso keine Ausnahmen auslösen.
Beispiel:
%Vor%Schauen Sie sich diese Frage von mir an die Antworten .
Grundsätzlich können Sie die gerade aktive Ausnahme mit einem einfachen throw
im ersten try-Block erneut auslösen. Dies ist jedoch nur dann sicher, wenn Sie sicher sind, dass gerade eine Ausnahme behandelt wird, dh der Destruktor wird innerhalb eines catch
-Blocks aufgerufen. Andernfalls ruft throw
% co_de auf %.
Das Auslösen von Ausnahmen innerhalb von Destruktoren ist jedoch verpönt, so dass ich die Ausnahmen danach nicht erneut ausführen würde. Am besten sieht das Ganze für mich nicht nach einer guten Idee aus.
Das Ausnahmebehandlungsmuster ist in Ordnung, aber ich würde es in einem nicht verwandten Destruktor nicht tun. Siehe auch die referenzierte Frage.
Es ist nicht möglich, auf eine sichere Weise zu tun.
Was Sie tun können, ist Ihre Parameter im Destruktor zu überprüfen, und das sollte sagen, ob die Verarbeitung abgeschlossen wurde.
Übrigens, warum protokollieren Sie nicht den Fehler im catch-Block, in dem Sie den Fehler tatsächlich behandeln können? Dort sollten Sie wissen, dass die Verarbeitung mit dem Fehler beendet wurde.
Tags und Links c++ exception raii destructor