Exception im Destruktor werfen - Alternativen?



  • Normalerweise ist es eine schlechte Idee, im Destruktor Exceptions zu werfen, da dies zur vollständigen Terminierung führen kann, wenn bereits eine Exception behandelt wird. Im vorliegenden Fall stellt sich jedoch die Frage, wie man damit umgehen kann, dass ein Objekt zum Zeitpunkt, wo der Destruktor aufgerufen wird, sich in einem ungültigen Zustand befindet.

    Hintergrund ist eine Steuerung mit (im Prinzip unendlich vielen) logischen Zuständen, für welche möglichst exakte Tests geschrieben werden sollen. Wenn ein Ablauf nicht korrekt war, dann befindet sich die Steuerung am Ende nicht im Null-Zustand, was einen Fehler signalisiert und eigentlich nicht sein darf.

    Wie signalisiere ich sowas am besten? Doch Exceptions? Assertions?



  • Steuerung s;
    s.doAblauf();
    if (s.state != Null_Zustand)
        cout << "Ablauf fehlgeschlagen";
    

    Mir ist völlig unklar wie man hier auf Exceptions kommt. Dass ein Test fehlschlägt ist ein völlig normales Resultat einer Testroutine, das entsprechend ausgegeben wird.



  • Also Checks erlauben und dann mit assert arbeiten?



  • Überleg mal: Ein Objekt ist so kaputt, dass man es nicht einmal mehr wegräumen kann. Wie willst du überhaupt in einen einigermaßen sicheren Zustand zurückkehren?

    Per Programmdesign sollte so ein Zustand nie auftreten, deswegen kann man auch kaum reagieren, außer das ganze Programm abzuschießen und ggf. noch eine Fehlermeldung ausgeben.
    assert ist selten falsch, weil es eine Fehlermedung im Debug und gute Geschwindigkeit im Release mode umsetzt, aber du kannst natürlich auch anders reagieren. Dennoch: Den Vorteil von Exceptions, dass du den Fehler bearbeiten kannst und danach wieder in einem brauchbaren Programmzustand bist, wirst du nicht erreichen (wollen).



  • Das ist wahr, denn es geht um einen Zustand, den es eigentlich nicht geben darf und welchen man ohne Neustart auch nicht mehr wirklich recovern kann. Also dann, assert. Danke.



  • Assert ist halt im Release-Modus weg und daher nur für die Entwickler nützlich. Da du von Testen sprichst, sollte das klappen. Falls das Problem beim Endbenutzer auftritt, krachts dafür umso fürchterlicher -- aber das passiert ja nicht, wenn du gut testest 😉



  • dass ein Objekt zum Zeitpunkt, wo der Destruktor aufgerufen wird, sich in einem ungültigen Zustand befindet

    Vom Design her sollte ein Objekt durch seine Methoden nicht in einen ungueltigen Zustand gebracht werden koennen. Stichwort: Invarianten. Wenn das doch passiert (bspw. wenn ein Device angesteuert wird), dann sind Exceptions genau der richtige Weg. Das tritt auf bzw. wird festgestellt, wenn Methoden des Objektes benutzt werden. D.h. Methoden sollten die Exception werfen, nicht der Destruktor.

    Also Checks erlauben und dann mit assert arbeiten?

    Nein, checks einbauen und mit throw abarbeiten. Und diese Checks sind innerhalb der Methoden zu finden und nicht ausserhalb der Klasse.

    Ausserdem: Also ein Objekt ist vor dem Destruktoraufruf ungueltig und hinterher eben nicht mehr existent. Wieso eine Exception werfen, wenn das Objekt hinterher sowieso weg ist?


Log in to reply