2017-02-27 3 views
0

Wenn Sie std::runtime_error werfen und nicht behandeln, druckt das Terminal automatisch das Ergebnis what(), was das Debugging erheblich vereinfacht. Beispiel:Wie kann ich what() aufrufen, nachdem eine nicht behandelte, benutzerdefinierte Ausnahme geworfen wurde?

#include <iostream> 

int main() 
{ 
    throw std::runtime_error("This is an error message.\n"); 
} 

Console Ausgabe:

terminate called after throwing an instance of 'std::runtime_error' 
what(): This is an error message. 

Benutzerdefinierte Ausnahmeklassen von dieser Klasse abgeleitet zeigen das gleiche Verhalten, Ausnahmeklassen von Grund auf neu gemacht tun das nicht standardmäßig aktiviert.

Aber die Ausnahmeklasse, die ich erstellen möchte, darf nicht von std::runtime_error abgeleitet werden. Und zum Debuggen sollte what() noch gedruckt werden, nachdem das Programm abstürzt - aber ich kann nicht herausfinden, wie das geht, egal was! Kann mir bitte jemand helfen?

Im Moment sieht es wie folgt aus:

#include <iostream> 

struct Custom_Exception 
{ 
    std::string Msg; 

    Custom_Exception(std::string Error_Msg) noexcept 
    { 
     Msg=Error_Msg; 
    } 

    std::string what() noexcept 
    { 
     return Msg; 
    } 
}; 

int main() 
{ 
    throw Custom_Exception("This is an error message.\n"); 
} 

Console Ausgabe:

terminate called after throwing an instance of 'Custom_Exception' 

Kein what(): in der Fehlermeldung ein std::cout<<Msg; in die destructor ... Putting entweder nicht hilft .

Bitte helfen Sie mir mit Ihren Vorschlägen! Vielen Dank.

+4

"Aber die Ausnahmeklasse, die ich erstellen möchte, darf nicht von std :: runtime_error abgeleitet sein." - Warum nicht? –

+2

Fangen Sie Ihre Ausnahmen in main und tun Sie, was Sie mit ihnen wollen. Ich würde mich nicht auf die Laufzeit verlassen, um das für Sie zu tun. –

+0

@NeilButterworth Es zwingt mich, bestimmte Datentypen zu verwenden oder jedes Mal zu konvertieren, es hindert mich daran, eine generische Ausnahmeklasse zu erstellen, die ich für meine eigenen Projekte verwenden möchte, ich möchte wissen, wie diese Funktion hinzugefügt werden kann Neugierde. Ich mag es einfach nicht so. Sonst könnte ich einfach std :: runtime_error selbst verwenden ... Aber ich möchte von der eigenen Exception-Klasse, weil es gewisse Dinge std :: runtime_error nicht kann. – Thynome

Antwort

4

Die minimale Ausnahme Schnittstelle what() mit den std::terminate_handler zu verwenden ist std::exception:

struct Custom_Exception : public std::exception { 
    std::string Msg; 
public: 
    Custom_Exception(std::string Error_Msg) noexcept : Msg(Error_Msg) { 
    } 

    const char* what() const { return Msg.c_str(); } 
}; 

Eine weitere Option, ohne von dem std::exception Schnittstelle zu vererben ist Ihre benutzerdefinierten Ausnahmen in main()

int main() 
{ 
    try { 
     throw Custom_Exception("This is an error message.\n"); 
    } 
    catch(const Custom_Exception& ce) { 
     std::cerr << ce.what() << std::endl; 
    } 
} 

zu fangen oder überschreiben und setzen Sie die mit Ihrer eigenen ha ndler.

+0

Kannst du erklären, wie man 'std :: terminate_handler' richtig überschreibt und wie ich es bitte in meine Ausnahmeklasse integrieren kann? – Thynome

+0

@Thynome Ich bin mir nicht endgültig sicher, ob eine 'std :: terminate_handler'-Überschreibungsfunktion erneut ausgelöst und abgefangen werden kann wie' try {throw; } catch (const Custom_Exception & ce) {/ * ... * /} '. –

+0

Sie können. [except.handle]/7 sagt, dass * ein impliziter Handler als aktiv betrachtet wird, wenn std :: terminate() [...] aufgrund eines throw * eingegeben wird, so dass Sie die Exception von dort sicher erneut ausgeben können. –

0

Sie sollten Ihre Ausnahme von std :: exception ableiten, die einen virtuellen Destruktor und die virtuelle was() -Methode bietet. Wenn Sie den Destruktor überschreiben, sollten Sie in der Lage sein, Ihre Nachricht zu drucken.

#include <iostream> 
#include <exception> 

class Custom_Exception : std::exception 
{ 
    char const* Msg; 

    Custom_Exception(char const* Error_Msg) noexcept 
    { 
     Msg=Error_Msg; 
    } 

    Custom_Exception(Custom_Exception const& other) 
    { 
     Msg = other.Msg; 
    } 

    Custom_Exception& operator=(Custom_Exception const& other) 
    { 
     Msg = other.Msg; 
     return *this; 
    } 

    virtual ~Custom_Exception() 
    { 
    } 

    virtual char const* what() const noexcept 
    { 
     return Msg; 
    } 
}; 

int main() 
{ 
    try 
    { 
     throw Custom_Exception("This is an error message.\n"); 
    } 
    catch (Custom_Exception& ex) 
    { 
     std::cout << "what(): " << ex.what(); 
    } 
} 
+0

Wird die Fehlermeldung nicht ausgegeben, auch wenn die Ausnahme nie ausgelöst wird? Und auch wenn es gefangen wird? –

+0

Oh, ja. Wann immer die Ausnahme zerstört wird. So könnte πάντα ῥεῖs Antwort mit dem äußeren Haken funktionieren. –

+0

Es ist nicht Aufgabe des Destruktors, die Fehlermeldung auszugeben. Deshalb existiert 'what()', um die Fehlermeldung zurückzugeben, wenn sie benötigt wird. –

Verwandte Themen