C++ Ausnahmebehandlung

Ausnahmen sind Probleme, die während der Programmausführung auftreten. C++-Ausnahmen beziehen sich auf besondere Situationen, die zur Laufzeit auftreten, wie z. B. der Versuch, durch null zu dividieren.

Ausnahmen bieten eine Möglichkeit, die Programmsteuerung zu übertragen. Die C++-Ausnahmebehandlung umfasst drei Schlüsselwörter:try, catch, throw。

  • throw:Wenn ein Problem auftritt, löst das Programm eine Ausnahme aus. Dies geschieht durch die Verwendung vonthrow. Es wird mithilfe von Schlüsselwörtern erreicht.
  • catch:Wo Sie das Problem behandeln möchten, fangen Sie die Ausnahme durch einen Ausnahmehandler ab.catchDas Schlüsselwort wird verwendet, um Ausnahmen abzufangen.
  • try: tryDer Code in einem Block identifiziert die spezifische Ausnahme, die ausgelöst wird. Darauf folgen normalerweise ein oder mehrere catch-Blöcke.

Wenn ein Block eine Ausnahme auslöst, verwendet die Methode zum Abfangen der Ausnahme dietryundcatchSchlüsselwörter. Code, der eine Ausnahme auslösen kann, wird in einen try-Block gesetzt, und der Code innerhalb des try-Blocks wird geschützter Code genannt. Die Syntax für die Verwendung einer try/catch-Anweisung lautet wie folgt:

try { // Code schützen }catch( ExceptionName e1 ) { // catch-Block }catch( ExceptionName e2 ) { // catch-Block }catch( ExceptionName eN ) { // catch-Block }

iftryBlöcke können in verschiedenen Kontexten unterschiedliche Ausnahmen auslösen; in diesem Fall können Sie versuchen, mehrerecatchAnweisungen aufzulisten, die verwendet werden, um verschiedene Arten von Ausnahmen abzufangen.

Eine Ausnahme auslösen

Sie könnenthrowverwenden. Die Anweisung löst an jeder Stelle im Codeblock eine Ausnahme aus. Der Operand der throw-Anweisung kann ein beliebiger Ausdruck sein, und der Typ des Ergebnisses des Ausdrucks bestimmt den Typ der ausgelösten Ausnahme.

Nachfolgend ein Beispiel für das Auslösen einer Ausnahme beim Versuch, durch null zu teilen:

double division(int a, int b) { if( b == 0 ) { throw "Division by zero condition!"; } return (a/b); }

Ausnahmen abfangen

catchBlock folgt auftry, wird nach dem Block platziert, um Ausnahmen abzufangen. Sie können den Typ der Ausnahme angeben, die Sie abfangen möchten; dieser wird durch die Ausnahmedeklaration in Klammern nach dem Schlüsselwort catch bestimmt.

try { // Code schützen }catch( ExceptionName e ) { // Code zur Behandlung der ExceptionName-Ausnahme }

Der obige Code fängt eine Ausnahme vom TypExceptionNameexception ab. Wenn ein catch-Block jede Art von Ausnahme behandeln soll, die von einem try-Block ausgelöst wird, müssen Sie eine Ellipse ... innerhalb der Klammern der Ausnahmedeklaration verwenden, wie unten gezeigt:

try { // Code schützen }catch(...) { // Code, der jede Ausnahme behandeln kann }

Hier ist ein Beispiel, das eine Division-durch-Null-Ausnahme auslöst und sie im catch-Block abfängt.

Beispiel

#include <iostream> using namespace std; double division(int a, int b) { if( b == 0 ) { throw "Division by zero condition!"; } return (a/b); } int main () { int x = 50; int y = 0; double z = 0; try { z = division(x, y); cout << z << endl; }catch (const char* msg) { cerr << msg << endl; } return 0; }

Da wir eine Ausnahme vom Typconst char*geworfen haben, müssen wir beim Abfangen dieser Ausnahme const char* im catch-Block verwenden. Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er die folgenden Ergebnisse:

Division by zero condition!

C++-Standardausnahmen

C++ stellt eine Reihe von Standardausnahmen bereit, die in<exception>definiert sind und die wir in Programmen verwenden können. Sie sind als Eltern-Kind-Klassenhierarchie organisiert, wie unten gezeigt:

C++ 异常的层次结构

Die folgende Tabelle beschreibt jede Ausnahme, die in der obigen Hierarchie vorkommt:

Ausnahme Beschreibung
std::exception Diese Ausnahme ist die Elternklasse aller Standard-C++-Ausnahmen.
std::bad_alloc Diese Ausnahme kann durchnewgeworfen werden.
std::bad_cast Diese Ausnahme kann durchdynamic_castgeworfen werden.
std::bad_typeid Diese Ausnahme kann durchtypeidgeworfen werden.
std::bad_exception Dies ist sehr nützlich beim Umgang mit Ausnahmen, die in einem C++-Programm nicht vorhersehbar sind.
std::logic_error Ausnahmen, die theoretisch durch Lesen des Codes erkannt werden können.
std::domain_error Diese Ausnahme wird geworfen, wenn ein ungültiger mathematischer Definitionsbereich verwendet wird.
std::invalid_argument Diese Ausnahme wird geworfen, wenn ein ungültiges Argument verwendet wird.
std::length_error Diese Ausnahme wird ausgelöst, wenn ein zu langer std::string erstellt wird.
std::out_of_range Diese Ausnahme kann von Methoden wie std::vector und std::bitset<>::operator[]() ausgelöst werden.
std::runtime_error Ausnahmen, die theoretisch nicht durch Lesen des Codes erkannt werden können.
std::overflow_error Diese Ausnahme wird ausgelöst, wenn ein mathematischer Überlauf auftritt.
std::range_error Diese Ausnahme wird ausgelöst, wenn versucht wird, einen Wert außerhalb des gültigen Bereichs zu speichern.
std::underflow_error Diese Ausnahme wird ausgelöst, wenn ein mathematischer Unterlauf auftritt.

Neue Ausnahmen definieren

Du kannst neue Ausnahmen definieren, indem du von derexception-Klasse erbst und sie überlädst. Das folgende Beispiel zeigt, wie du die std::exception-Klasse verwendest, um deine eigenen Ausnahmen zu implementieren:

Beispiel

#include <iostream> #include <exception> using namespace std; struct MyException : public exception { const char * what () const throw () { return "C++ Exception"; } }; int main() { try { throw MyException(); } catch(MyException& e) { std::cout << "MyException caught" << std::endl; std::cout << e.what() << std::endl; } catch(std::exception& e) { // Andere Fehler } }

Dies erzeugt das folgende Ergebnis:

MyException caught
C++ Exception

Hier istwhat()eine öffentliche Methode, die von der Exception-Klasse bereitgestellt wird und von allen abgeleiteten Exception-Klassen überschrieben wurde. Sie gibt die Ursache der Exception zurück.

Weitere Erweiterungen