Was ist der Unterschied zwischen std::runtime_error
und std::exception
? Was ist die richtige Verwendung für jeden? Warum sind sie überhaupt anders?Unterschied: std :: runtime_error vs std :: exception()
Antwort
std::exception
ist die Klasse, deren einziger Zweck darin besteht, als Basisklasse in der Ausnahmehierarchie zu dienen. Es hat keine anderen Anwendungen. Mit anderen Worten, konzeptionell ist es eine abstrakte Klasse (obwohl sie nicht als abstrakte Klasse in C++ definiert ist, was den Begriff bedeutet).
std::runtime_error
ist eine speziellere Klasse von std::exception
absteigend, bestimmt bei verschiedenen Laufzeit Fehler geworfen werden. Es hat einen doppelten Zweck. Es kann von selbst ausgelöst werden, oder es kann als Basisklasse für verschiedene, noch speziellere Arten von Laufzeitfehlerausnahmen dienen, wie std::range_error
, std::overflow_error
usw. Sie können eigene Ausnahmeklassen definieren, die von std::runtime_error
abstammen, sowie Sie definieren können Ihre eigenen Ausnahmeklassen, die von std::exception
abstammen.
Genau wie std::runtime_error
enthält die Standardbibliothek std::logic_error
, ebenfalls absteigend von std::exception
.
Der Zweck dieser Hierarchie besteht darin, dem Benutzer die Möglichkeit zu geben, die volle Leistungsfähigkeit des C++ - Ausnahmebehandlungsmechanismus zu nutzen. Da die 'catch' -Klausel polymorphe Ausnahmen abfangen kann, kann der Benutzer 'catch' -Klauseln schreiben, die Ausnahmetypen von einem bestimmten Teilbaum der Ausnahmehierarchie abfangen können. Zum Beispiel fängt catch (std::runtime_error& e)
alle Ausnahmen von std::runtime_error
Teilbaum, lassen Sie alle anderen passieren (und fliegen weiter nach oben auf den Call-Stack).
P.S. Das Entwickeln einer nützlichen Ausnahmeklassenhierarchie (mit der Sie nur die Ausnahmetypen abfangen können, an denen Sie an jedem Punkt Ihres Codes interessiert sind) ist eine nicht-triviale Aufgabe. Was Sie in der Standard-C++ - Bibliothek sehen, ist ein möglicher Ansatz, der Ihnen von den Autoren der Sprache angeboten wird. Wie Sie sehen, haben sie sich dafür entschieden, alle Ausnahmetypen in "Laufzeitfehler" und "Logikfehler" aufzuteilen und von dort aus mit eigenen Ausnahmetypen fortzufahren. Es gibt natürlich alternative Möglichkeiten, diese Hierarchie zu strukturieren, die für Ihr Design geeigneter sein könnte.
Update: Portabilität Linux vs Windows-
Als Loki Astari und unixman83 in ihrer Antwort zur Kenntnis genommen und Kommentaren unten, der Konstruktor der exception
Klasse nimmt keine Argumente nach C++ Standard. Microsoft C++ hat einen Konstruktor, der Argumente in der Klasse exception
nimmt, aber dies ist kein Standard. Die Klasse runtime_error
hat einen Konstruktor, der auf beiden Plattformen, Windows und Linux, Argumente entgegennimmt (char*
). Um tragbar zu sein, verwenden Sie besser runtime_error
.
(Und denken Sie daran, nur weil eine Spezifikation des Projekts sagt Ihr Code nicht auf Linux laufen hat, bedeutet es nicht, es nie auf Linux laufen muss.)
std :: Ausnahme sein sollte berücksichtigt (beachten Sie die Überlegung) die abstrakte Basis der Standardausnahmehierarchie. Dies liegt daran, dass es keinen Mechanismus gibt, um eine bestimmte Nachricht zu übergeben (dazu müssen Sie what()) ableiten und spezialisieren. Es gibt nichts, was Sie daran hindern könnte, std :: exception zu verwenden, und für einfache Anwendungen könnte es alles sein, was Sie brauchen.
std :: runtime_error auf der anderen Seite hat gültige Konstruktoren, die eine Zeichenfolge als Nachricht akzeptieren.Wenn what() aufgerufen wird, wird ein const char-Zeiger zurückgegeben, der auf eine C-Zeichenfolge zeigt, die die gleiche Zeichenfolge hat, die an den Konstruktor übergeben wurde.
try
{
if (badThingHappened)
{
throw std::runtime_error("Something Bad happened here");
}
}
catch(std::exception const& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
Danke für die Antwort Martin. Allerdings verwende ich std :: exception() auf die gleiche Weise wie oben beschrieben. h., std :: exception() -Konstruktor kann auch eine std :: string() oder const char * nehmen. – sivabudh
Nicht gemäß der Norm. std :: exception hat einen Konstruktor, der keine Argumente annimmt. Das Verwenden einer Version, die eine Std :: Zeichenfolge oder eine C-Zeichenfolge akzeptiert, ist nicht portierbar. –
Aufgrund von Microsoft habe ich mich daran gewöhnt, 'std :: exception (std :: string)' zu werfen. Jetzt erkenne ich, dass ich 'std :: runtime_error' werfen muss, wenn ich möchte, dass mein Code in Linux (GCC) funktioniert. – unixman83
- 1. Verwirrt über std :: runtime_error vs. std :: logic_error
- 2. Fehler beim Abfangen von std :: runtime_error als std :: exception
- 3. throw new std :: exception vs throw std :: exception
- 4. Unterschied zwischen std :: exception und "..."
- 5. move constructor für std :: runtime_error
- 6. Unterschied in using namespace (std :: vs :: std: :)
- 7. std :: mem_fun vs std :: mem_fn
- 8. Wie vererbt man von std :: runtime_error?
- 9. std :: exception 's was() gibt "std :: exception" zurück
- 10. std :: unique_ptr vs std :: shared_ptr vs std :: weak_ptr vs std :: auto_ptr vs raw Zeigern
- 11. std :: konditional vs std :: enable_if
- 12. Sind der Kopierkonstruktor und die Kopierzuordnung von std :: runtime_error noexcept?
- 13. Leistung std :: strstr vs. std :: string ::
- 14. C++ Aufrufstack von std :: exception
- 15. Unterschied zwischen std :: uninitialized_copy & std :: copy?
- 16. Unterschied zwischen Std: String und Std :: String
- 17. Unterschied zwischen std :: Suche und std :: find_first_of
- 18. Unterschied zwischen std :: regex_match & std :: regex_search?
- 19. Unterschied zwischen std :: set und std :: priority_queue
- 20. Wann std :: async vs. std :: threads verwenden?
- 21. Vererbung von std :: exception, Mehrdeutigkeit in den Definitionen von std :: exception
- 22. Wurf std :: runtime_error innerhalb OpenMP Region stürzt das Programm
- 23. C++ Ausnahmen: Warum std :: exception verwenden oder erweitern?
- 24. std :: vector vs normalen Array
- 25. std :: mit std :: make_pair
- 26. C++ Ausnahmen und Vererbung von std :: exception
- 27. std :: string und std :: ios :: binary
- 28. Was ist der Unterschied zwischen std :: cout und std :: wcout?
- 29. Was ist der Unterschied zwischen std :: set und std :: map
- 30. Was ist der Unterschied zwischen std :: partial_sum und std :: inclusive_scan?
danke. gute Antwort. obwohl ich mich frage, ob es jemals eine andere art von ausnahme geben muss ... nur ein gedanke. – sivabudh
Wenn es eine Toleranz gibt, von der die Ausnahme erneut abgedeckt werden kann, kann eine andere Art von Ausnahme nützlich sein, da wir den Ausnahmebehandlungsmechanismus verwenden können, um die Ausnahme an den Handler zu verweisen, der das Problem beheben wird. Wenn es keine Chance auf Wiederherstellung gibt, ist eine der Standardausnahmen in Ordnung. –
Nur als Nebenbemerkung: Es gibt nirgendwo eine Regel, die Sie zwingt, von 'std :: exception' abzuleiten. Sicher, alle 'std' Dinge werfen davon abgeleitete Klassen ab, aber es gibt absolut keinen Grund, nur" std :: exception "abgeleitete Objekte zu werfen. – rubenvb