Gestione delle eccezioni C ++
Un'eccezione è un problema che sorge durante l'esecuzione di un programma. Un'eccezione C ++ è una risposta a una circostanza eccezionale che si verifica mentre un programma è in esecuzione, come un tentativo di divisione per zero.
Le eccezioni forniscono un modo per trasferire il controllo da una parte all'altra di un programma. La gestione delle eccezioni C ++ si basa su tre parole chiave:try, catch, e throw.
throw- Un programma genera un'eccezione quando si presenta un problema. Questo viene fatto utilizzando un filethrow parola chiave.
catch- Un programma rileva un'eccezione con un gestore di eccezioni nel punto in cui si desidera gestire il problema. Ilcatch la parola chiave indica la cattura di un'eccezione.
try - A tryblocco identifica un blocco di codice per il quale verranno attivate particolari eccezioni. È seguito da uno o più blocchi di cattura.
Supponendo che un blocco solleverà un'eccezione, un metodo cattura un'eccezione utilizzando una combinazione di try e catchparole chiave. Un blocco try / catch viene posizionato attorno al codice che potrebbe generare un'eccezione. Il codice all'interno di un blocco try / catch viene indicato come codice protetto e la sintassi per l'utilizzo di try / catch è la seguente:
try {
// protected code
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
}
Puoi elencare più file catch istruzioni per catturare diversi tipi di eccezioni nel caso in cui il tuo try block solleva più di un'eccezione in diverse situazioni.
Lanciare eccezioni
Le eccezioni possono essere generate ovunque all'interno di un blocco di codice utilizzando throwdichiarazione. L'operando dell'istruzione throw determina un tipo per l'eccezione e può essere qualsiasi espressione e il tipo del risultato dell'espressione determina il tipo di eccezione generata.
Di seguito è riportato un esempio di generazione di un'eccezione quando si verifica la condizione di divisione per zero:
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
Catturare le eccezioni
Il catch blocco seguendo il tryblock cattura qualsiasi eccezione. È possibile specificare il tipo di eccezione che si desidera catturare e questo è determinato dalla dichiarazione di eccezione che appare tra parentesi dopo la parola chiave catch.
try {
// protected code
} catch( ExceptionName e ) {
// code to handle ExceptionName exception
}
Il codice precedente rileverà un'eccezione di ExceptionNamegenere. Se si desidera specificare che un blocco catch deve gestire qualsiasi tipo di eccezione generata in un blocco try, è necessario inserire un'ellissi, ..., tra le parentesi che racchiudono la dichiarazione di eccezione come segue:
try {
// protected code
} catch(...) {
// code to handle any exception
}
Il seguente è un esempio, che genera un'eccezione di divisione per zero e la catturiamo nel blocco catch.
#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;
}
Perché stiamo sollevando un'eccezione di tipo const char*, quindi mentre si cattura questa eccezione, dobbiamo usare const char * nel blocco catch. Se compiliamo ed eseguiamo il codice sopra, questo produrrebbe il seguente risultato:
Division by zero condition!
Eccezioni standard C ++
C ++ fornisce un elenco di eccezioni standard definite in <exception>che possiamo utilizzare nei nostri programmi. Questi sono organizzati in una gerarchia di classi genitore-figlio mostrata di seguito:
Ecco la piccola descrizione di ciascuna eccezione menzionata nella gerarchia precedente:
Suor n | Eccezione e descrizione |
---|---|
1 | std::exception Un'eccezione e una classe genitore di tutte le eccezioni C ++ standard. |
2 | std::bad_alloc Questo può essere lanciato da new. |
3 | std::bad_cast Questo può essere lanciato da dynamic_cast. |
4 | std::bad_exception Questo è un dispositivo utile per gestire eccezioni impreviste in un programma C ++. |
5 | std::bad_typeid Questo può essere lanciato da typeid. |
6 | std::logic_error Un'eccezione che teoricamente può essere rilevata leggendo il codice. |
7 | std::domain_error Questa è un'eccezione generata quando viene utilizzato un dominio matematicamente non valido. |
8 | std::invalid_argument Questo viene generato a causa di argomenti non validi. |
9 | std::length_error Viene generato quando viene creato uno std :: string troppo grande. |
10 | std::out_of_range Questo può essere lanciato dal metodo 'at', ad esempio un std :: vector e std :: bitset <> :: operator [] (). |
11 | std::runtime_error Un'eccezione che teoricamente non può essere rilevata leggendo il codice. |
12 | std::overflow_error Viene generato se si verifica un overflow matematico. |
13 | std::range_error Ciò si verifica quando si tenta di memorizzare un valore fuori intervallo. |
14 | std::underflow_error Viene generato se si verifica un underflow matematico. |
Definisci nuove eccezioni
È possibile definire le proprie eccezioni ereditando e sovrascrivendo exceptionfunzionalità di classe. Di seguito è riportato l'esempio, che mostra come è possibile utilizzare la classe std :: exception per implementare la propria eccezione in modo standard -
#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) {
//Other errors
}
}
Ciò produrrebbe il seguente risultato:
MyException caught
C++ Exception
Qui, what()è un metodo pubblico fornito dalla classe di eccezione ed è stato sovrascritto da tutte le classi di eccezione figlio. Ciò restituisce la causa di un'eccezione.