Ich habe einige Objekte auf dem Stapel in der Hauptfunktion:
%Vor%Außerdem habe ich eine Funktion, die Fehler in meiner Anwendung verfolgt:
%Vor%Die Err-Funktion ist definitiv nützlich, wenn ich einen schwerwiegenden Fehler melden muss. Ich protokolliere nur den Fehler und beende die Anwendung - sie kann nach solchen Fehlern nicht wiederhergestellt werden. Das Beenden mit "exit ()" ruft foo und bar-Destruktoren jedoch nicht auf - ein Verhalten, das ich eigentlich erwartet hatte (aber falsch war). "abort ()" hilft auch nicht. Außerdem kann ich Ausnahmen nicht verwenden , um sie in main () abzufangen. Gibt es eine andere Möglichkeit, die Err-Funktion so zu implementieren, dass sie die App beendet und die Stack-Objekte korrekt reinigt? Oder sollte ich meine Fehlerbehandlung irgendwie neu gestalten?
Danke!
ps. Übrigens, kann ich keine WM_QUIT-Nachricht an mein Hauptfenster senden? Ich bin nicht gut mit WinAPI, aber meine App ist reines Win32 und meine Err () - Funktion kann ein Handle zu meinem Hauptfenster bekommen. Wird es funktionieren?
Nicht ohne Ausnahmen oder normale Rückkehr von Err bis zum Callstack. Sie müssen den Stapel abwickeln.
Es gibt immer noch C's setjmp
und longjmp
. Es sollte dich zurück nach main
bringen, also würde das Programm wie üblich nach Verlassen des Bereichs von main
enden, in welchem Fall C ++ 's Destruktor-Mechanismus deine lokalen Objekte in main
zerstören wird.
Natürlich ist die Verwendung von longjmp
in C ++ aus guten Gründen verpönt. Es überspringt alle anderen Funktionen auf dem Stapel, so dass es wirklich nur für einige Stapelobjekte in main
funktioniert.
Es könnte einfacher sein, Ihre Objekte auf dem Heap und delete
sie manuell in Err
zuzuweisen.
Es gibt grundsätzlich zwei Methoden, um Fehler in C ++ zu verbreiten: Ausnahmen (die Sie scheinbar willkürlich ausgeschlossen haben) und Rückgabecodes.
Da Sie keine Ausnahmen verwenden können, müssen Sie die Rückkehrcodes von Ihren Funktionen, die möglicherweise fehlschlagen, weiterleiten und sie testen, um zu sehen, ob Sie anhalten und zurück zur Hauptfunktion zurückkehren müssen. Wenn Sie den Stapel nicht so abwickeln, können Sie nicht garantieren, dass Destruktoren korrekt aufgerufen werden.
Bedenken Sie auch, dass Destruktoren tatsächlich in der Lage sein werden, wenn Ihr Programm in einem fatalen Zustand ist? Was ist, wenn der Objektstatus fehlerhaft ist und nicht ordnungsgemäß entfernt werden kann? Anstatt exit aufzurufen, könntest du abort
aufrufen, was zumindest einen Kern übrig lassen würde, um das Problem zu diagnostizieren, wenn du in einen schlechten Zustand kommst. Für schwerwiegende Fehler, bei denen Ausnahmen nicht verfügbar sind, ist dies eine vernünftige Wahl.
Ich glaube, Exit
wird die Anwendung sofort beenden. Um das erwartete Verhalten zu sehen, müssen foo
und bar
den Gültigkeitsbereich verlassen. Das bedeutet, dass die Hauptfunktion normalerweise mit einem Rückgabewert enden müsste. Anstatt Exit()
aus Ihrer Err-Funktion heraus aufzurufen, müssen Sie einen Weg finden, um zu Ihrer Hauptfunktion zurückzukehren und sie normal mit einem Fehlerwert zurückkehren zu lassen.
Ich würde Ihre Fehlerbehandlung neu gestalten. Am einfachsten ist es, wenn Sie das Steuerelement an main
zurückgeben und es normal säubern lassen. Ausnahmen bieten diese Funktion durch Abwickeln des Stapels, aber Sie können keine Ausnahmen verwenden. OK das passt. Manchmal können Sie Ausnahmen nicht verwenden.
Anstatt Err
zu versuchen, das Programm herunterzufahren, muss Err
den Fehler protokollieren und einen Fehlercode zurückgeben. Idealerweise sollte Err
sowieso nicht zwei Jobs ausführen, die Sie versuchen wollen: 1) Protokollieren Sie den Fehler, 2) Beenden Sie die Anwendung ordnungsgemäß.
Wenn Ihre Anwendung zufällig Multithread ist, haben Sie möglicherweise einen fehlerfreien easy out. Melden Sie im Fehlerprotokollierungsthread ein "Die" -Ereignis. Lassen Sie den Hauptthread auf dieses Ereignis warten und warten Sie auf weitere Aktionen (oder geben Sie einen Job über QueueUserAPC
oder ähnliches ein). Wenn das Ereignis gemeldet wird, schließen Sie die App.
Tags und Links c++ windows stack destructor exit