logo

Ausnahmebehandlung in C++

In C++ sind Ausnahmen Laufzeitanomalien oder ungewöhnliche Bedingungen, auf die ein Programm während seiner Ausführung stößt. Der Prozess der Behandlung dieser Ausnahmen wird Ausnahmebehandlung genannt. Mithilfe des Ausnahmebehandlungsmechanismus kann die Kontrolle von einem Teil des Programms, in dem die Ausnahme aufgetreten ist, auf einen anderen Teil des Codes übertragen werden.

Mit der Ausnahmebehandlung in C++ können wir also grundsätzlich die Ausnahmen behandeln, sodass unser Programm weiter ausgeführt wird.



String-Array in C-Sprache

Was ist eine C++-Ausnahme?

Eine Ausnahme ist ein unerwartetes Problem, das während der Ausführung eines Programms auftritt. Unser Programm wird plötzlich mit einigen Fehlern/Problemen beendet. Ausnahme tritt während der Ausführung des Programms (Laufzeit) auf.

Arten von C++-Ausnahmen

In C++ gibt es zwei Arten von Ausnahmen

  1. Synchron: Ausnahmen treten auf, wenn aufgrund eines Fehlers in den Eingabedaten etwas schief geht oder wenn das Programm nicht in der Lage ist, den aktuellen Datentyp zu verarbeiten, mit dem es arbeitet, beispielsweise das Teilen einer Zahl durch Null.
  2. Asynchron : Ausnahmen, die außerhalb der Kontrolle des Programms liegen, wie z. B. Festplattenfehler, Tastaturunterbrechungen usw.

C++ versuchen und fangen

C++ bietet eine integrierte Funktion zur Ausnahmebehandlung. Dies kann mit den folgenden speziellen Schlüsselwörtern erfolgen: Versuchen, Fangen und Werfen, wobei jedes einen anderen Zweck hat.



Syntax von Try-Catch in C++

  try   {     // Code that might throw an exception          throw   SomeExceptionType('Error message');  }    catch  ( ExceptionName e1 ) {     // catch block catches the exception that is thrown from try block   }>

1. Versuchen Sie es in C++

Das Schlüsselwort try stellt einen Codeblock dar, der eine im Try-Block platzierte Ausnahme auslösen kann. Es folgen ein oder mehrere Catch-Blöcke. Wenn eine Ausnahme auftritt, versucht der Block, diese Ausnahme auszulösen.

2. Fang in C++

Die Catch-Anweisung stellt einen Codeblock dar, der ausgeführt wird, wenn eine bestimmte Ausnahme vom Try-Block ausgelöst wird. Der Code zur Behandlung der Ausnahme wird in den Catch-Block geschrieben.

3. Wirf C++ ein

Eine Ausnahme in C++ kann mit dem Schlüsselwort throw ausgelöst werden. Wenn ein Programm auf eine throw-Anweisung stößt, beendet es sofort die aktuelle Funktion und beginnt mit der Suche nach einem passenden Catch-Block zur Behandlung der ausgelösten Ausnahme.



Notiz: Mehrere Catch-Anweisungen können verwendet werden, um verschiedene Arten von Ausnahmen abzufangen, die vom Try-Block ausgelöst werden.

Die Schlüsselwörter try und Catch kommen paarweise vor: Wir verwenden den Try-Block, um Code zu testen. Wenn der Code eine Ausnahme auslöst, behandeln wir diese in unserem Catch-Block.

Warum brauchen wir Ausnahmebehandlung in C++?

Im Folgenden sind die Hauptvorteile der Ausnahmebehandlung gegenüber der herkömmlichen Fehlerbehandlung aufgeführt:

  1. Trennung des Fehlerbehandlungscodes vom normalen Code : In herkömmlichen Fehlerbehandlungscodes gibt es immer if-else-Bedingungen zur Behandlung von Fehlern. Diese Bedingungen und der Code zur Fehlerbehandlung werden mit dem normalen Ablauf verwechselt. Dadurch wird der Code weniger lesbar und wartbar. Mit Try/Catch-Blöcken wird der Code für die Fehlerbehandlung vom normalen Ablauf getrennt.
  2. Funktionen/Methoden können nur die von ihnen ausgewählten Ausnahmen verarbeiten : Eine Funktion kann viele Ausnahmen auslösen, kann sich aber auch dafür entscheiden, einige davon zu behandeln. Die anderen Ausnahmen, die ausgelöst, aber nicht abgefangen werden, können vom Aufrufer behandelt werden. Wenn der Anrufer entscheidet, sie nicht abzufangen, werden die Ausnahmen vom Anrufer des Anrufers behandelt.
    In C++ kann eine Funktion die Ausnahmen angeben, die sie auslöst, indem sie das Schlüsselwort throw verwendet. Der Aufrufer dieser Funktion muss die Ausnahme auf irgendeine Weise behandeln (entweder durch erneute Angabe oder Abfangen).
  3. Gruppierung von Fehlertypen : In C++ können sowohl Basistypen als auch Objekte als Ausnahmen ausgelöst werden. Wir können eine Hierarchie von Ausnahmeobjekten erstellen, Ausnahmen in Namespaces oder Klassen gruppieren und sie nach ihren Typen kategorisieren.

Beispiele für die Ausnahmebehandlung in C++

Die folgenden Beispiele veranschaulichen die Verwendung eines Try-Catch-Blocks zur Behandlung von Ausnahmen in C++.

Beispiel 1

Das folgende Beispiel veranschaulicht das Auslösen von Ausnahmen in C++.

C++




// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >int> numerator = 10;> >int> denominator = 0;> >int> res;> >// check if denominator is 0 then throw runtime> >// error.> >if> (denominator == 0) {> >throw> runtime_error(> >'Division by zero not allowed!'>);> >}> >// calculate result if no exception occurs> >res = numerator / denominator;> >//[printing result after division> >cout <<>'Result after division: '> << res << endl;> >}> >// catch block to catch the thrown exception> >catch> (>const> exception& e) {> >// print the exception> >cout <<>'Exception '> << e.what() << endl;> >}> >return> 0;> }>

>

>

Ausgabe

Exception Division by zero not allowed!>

Beispiel 2

Das Folgende ist ein einfaches Beispiel, um die Ausnahmebehandlung in C++ zu zeigen. Die Ausgabe des Programms erklärt den Ablauf der Ausführung von Try/Catch-Blöcken.

CPP




shloka mehta
// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> using> namespace> std;> int> main()> {> >int> x = -1;> >// Some code> >cout <<>'Before try '>;> >// try block> >try> {> >cout <<>'Inside try '>;> >if> (x <0) {> >// throwing an exception> >throw> x;> >cout <<>'After throw (Never executed) '>;> >}> >}> >// catch block> >catch> (>int> x) {> >cout <<>'Exception Caught '>;> >}> >cout <<>'After catch (Will be executed) '>;> >return> 0;> }>

>

>

Ausgabe

Before try Inside try Exception Caught After catch (Will be executed)>

Eigenschaften der Ausnahmebehandlung in C++

Eigentum 1

Es gibt einen speziellen Catch-Block namens „Catch-All“-Block, geschrieben als Catch(…), der zum Abfangen aller Arten von Ausnahmen verwendet werden kann.

Beispiel

Im folgenden Programm wird als Ausnahme ein int ausgelöst, es gibt jedoch keinen Catch-Block für int, daher wird der Catch(…)-Block ausgeführt.

CPP




// C++ program to demonstate the use of catch all> // in exception handling.> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >// throw> >throw> 10;> >}> >// catch block> >catch> (>char>* excp) {> >cout <<>'Caught '> << excp;> >}> >// catch all> >catch> (...) {> >cout <<>'Default Exception '>;> >}> >return> 0;> }>

>

>

Ausgabe

Default Exception>

Eigentum 2

Für primitive Typen findet keine implizite Typkonvertierung statt.

Beispiel

Im folgenden Programm wird „a“ nicht implizit in int umgewandelt.

CPP




//// C++ program to demonstate property 2: Implicit type> /// conversion doesn't happen for primitive types.> // in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '> << x;> >}> >catch> (...) {> >cout <<>'Default Exception '>;> >}> >return> 0;> }>

>

>

Ausgabe

Default Exception>

Ausgabe:

Kern-Java-Sprache
Default Exception>

Eigentum 3

Wenn eine Ausnahme ausgelöst und nirgendwo abgefangen wird, wird das Programm abnormal beendet.

Beispiel

Im folgenden Programm wird ein Zeichen geworfen, es gibt jedoch keinen Catch-Block zum Abfangen des Zeichens.

CPP




// C++ program to demonstate property 3: If an exception is> // thrown and not caught anywhere, the program terminates> // abnormally in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '>;> >}> >return> 0;> }>

>

>

Ausgabe

terminate called after throwing an instance of 'char'>

Wir können dieses abnormale Beendigungsverhalten ändern, indem wir unsere unerwartete Funktion schreiben.

Notiz : Eine abgeleitete Klassenausnahme sollte vor einer Basisklassenausnahme abgefangen werden.

Wie Java verfügt auch die C++-Bibliothek über eine Standardausnahme Klasse, die die Basisklasse für alle Standardausnahmen ist. Alle von den Komponenten der Standardbibliothek ausgelösten Objekte werden von dieser Klasse abgeleitet. Daher können alle Standardausnahmen durch Abfangen dieses Typs abgefangen werden.

Eigentum 4

Im Gegensatz zu Java sind in C++ alle Ausnahmen ungeprüft, d. h. der Compiler prüft nicht, ob eine Ausnahme abgefangen wird oder nicht (siehe Das für Details). Daher ist es nicht notwendig, alle nicht abgefangenen Ausnahmen in einer Funktionsdeklaration anzugeben. Für die Ausnahmebehandlung wird dies jedoch empfohlen.

Beispiel

Das folgende Programm lässt sich gut kompilieren, aber idealerweise sollte die Signatur von fun() die ungeprüften Ausnahmen auflisten.

CPP




// C++ program to demonstate property 4 in exception> // handling.> #include> using> namespace> std;> // This function signature is fine by the compiler, but not> // recommended. Ideally, the function should specify all> // uncaught exceptions and function signature should be> // 'void fun(int *ptr, int x) throw (int *, int)'> void> fun(>int>* ptr,>int> x)> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }>

>

>

Ausgabe

Caught exception from fun()>

Eine bessere Möglichkeit, den obigen Code zu schreiben:

CPP

für String-Array Java




// C++ program to demonstate property 4 in better way> #include> using> namespace> std;> // Here we specify the exceptions that this function> // throws.> void> fun(>int>* ptr,>int> x)>throw>(> >int>*,>int>)>// Dynamic Exception specification> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }>

>

>

Ausgabe

Caught exception from fun()>

Notiz : Die Verwendung der dynamischen Ausnahmespezifikation ist seit C++11 veraltet. Einer der Gründe dafür kann sein, dass Ihr Programm zufällig abgebrochen werden kann. Dies kann passieren, wenn Sie eine Ausnahme eines anderen Typs auslösen, der nicht in der dynamischen Ausnahmespezifikation erwähnt wird. Ihr Programm bricht sich selbst ab, da es in diesem Szenario (indirekt)terminate() aufruft, was standardmäßig abort() aufruft.

Eigentum 5

In C++ können Try/Catch-Blöcke verschachtelt werden. Außerdem kann eine Ausnahme mithilfe von throw erneut ausgelöst werden. .

Beispiel

Das folgende Programm zeigt die Verschachtelung von Try/Catch-Blöcken.

CPP




// C++ program to demonstrate try/catch blocks can be nested> // in C++> #include> using> namespace> std;> int> main()> {> >// nesting of try/catch> >try> {> >try> {> >throw> 20;> >}> >catch> (>int> n) {> >cout <<>'Handle Partially '>;> >throw>;>// Re-throwing an exception> >}> >}> >catch> (>int> n) {> >cout <<>'Handle remaining '>;> >}> >return> 0;> }>

So konvertieren Sie einen String in Java in einen Int-Wert

>

>

Ausgabe

Handle Partially Handle remaining>

Eine Funktion kann eine Funktion auch erneut auslösen, indem sie denselben Wurf verwendet. Syntax. Eine Funktion kann einen Teil verarbeiten und den Aufrufer auffordern, den Rest zu bearbeiten.

Eigentum 6

Wenn eine Ausnahme ausgelöst wird, werden alle im umschließenden Try-Block erstellten Objekte zerstört, bevor die Steuerung an den Catch-Block übertragen wird.

Beispiel

Das folgende Programm demonstriert die obige Eigenschaft.

CPP




// C++ program to demonstrate> #include> using> namespace> std;> // Define a class named Test> class> Test {> public>:> >// Constructor of Test> >Test() { cout <<>'Constructor of Test '> << endl; }> >// Destructor of Test> >~Test() { cout <<>'Destructor of Test '> << endl; }> };> int> main()> {> >try> {> >// Create an object of class Test> >Test t1;> >// Throw an integer exception with value 10> >throw> 10;> >}> >catch> (>int> i) {> >// Catch and handle the integer exception> >cout <<>'Caught '> << i << endl;> >}> }>

>

>

Ausgabe

Constructor of Test Destructor of Test Caught 10>

Einschränkungen der Ausnahmebehandlung in C++

Auch die Ausnahmebehandlung in C++ unterliegt einigen Einschränkungen:

  • Ausnahmen können die Struktur oder den Fluss des Codes unterbrechen, da im Code mehrere unsichtbare Ausstiegspunkte erstellt werden, was das Lesen und Debuggen des Codes erschwert.
  • Wenn die Ausnahmebehandlung nicht ordnungsgemäß durchgeführt wird, kann dies ebenfalls zu Ressourcenlecks führen.
  • Es ist schwer zu lernen, wie man sicheren Ausnahmecode schreibt.
  • Es gibt keinen C++-Standard für die Verwendung der Ausnahmebehandlung, daher gibt es viele Variationen bei den Ausnahmebehandlungspraktiken.

Abschluss

Die Ausnahmebehandlung in C++ dient zur Bewältigung unerwarteter Ereignisse mithilfe von Try- und Catch-Blöcken, um das Problem effizient zu verwalten. Diese Ausnahmebehandlung macht unsere Programme zuverlässiger, da Fehler zur Laufzeit separat behandelt werden können, und sie trägt außerdem dazu bei, einen Programmabsturz und ein abruptes Beenden des Programms zu verhindern, wenn ein Fehler auftritt.

In Verbindung stehende Artikel:

  • Die wichtigsten Fragen und Antworten im Vorstellungsgespräch zur C++-Ausnahmebehandlung
  • Quiz zur Ausnahmebehandlung in C++