Manejo de excepciones de C ++
Una excepción es un problema que surge durante la ejecución de un programa. Una excepción de C ++ es una respuesta a una circunstancia excepcional que surge mientras se ejecuta un programa, como un intento de dividir por cero.
Las excepciones proporcionan una forma de transferir el control de una parte de un programa a otra. El manejo de excepciones de C ++ se basa en tres palabras clave:try, catch, y throw.
throw- Un programa lanza una excepción cuando aparece un problema. Esto se hace usando unthrow palabra clave.
catch- Un programa detecta una excepción con un controlador de excepciones en el lugar de un programa en el que desea manejar el problema. loscatch La palabra clave indica la captura de una excepción.
try - A trybloque identifica un bloque de código para el cual se activarán excepciones particulares. Le sigue uno o más bloques de captura.
Suponiendo que un bloque generará una excepción, un método detecta una excepción usando una combinación de try y catchpalabras clave. Se coloca un bloque try / catch alrededor del código que podría generar una excepción. El código dentro de un bloque try / catch se conoce como código protegido, y la sintaxis para usar try / catch es la siguiente:
try {
// protected code
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
}
Puede enumerar varios catch declaraciones para detectar diferentes tipos de excepciones en caso de que su try block genera más de una excepción en diferentes situaciones.
Lanzar excepciones
Las excepciones se pueden lanzar en cualquier lugar dentro de un bloque de código usando throwdeclaración. El operando de la instrucción throw determina un tipo para la excepción y puede ser cualquier expresión y el tipo del resultado de la expresión determina el tipo de excepción lanzada.
A continuación se muestra un ejemplo de cómo lanzar una excepción cuando se produce la condición de división por cero:
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
Captura de excepciones
los catch bloque siguiendo el trybloque detecta cualquier excepción. Puede especificar qué tipo de excepción desea capturar y esto está determinado por la declaración de excepción que aparece entre paréntesis después de la palabra clave catch.
try {
// protected code
} catch( ExceptionName e ) {
// code to handle ExceptionName exception
}
El código anterior detectará una excepción de ExceptionNametipo. Si desea especificar que un bloque de captura debe manejar cualquier tipo de excepción que se lanza en un bloque de prueba, debe poner una elipsis, ..., entre los paréntesis que encierran la declaración de excepción de la siguiente manera:
try {
// protected code
} catch(...) {
// code to handle any exception
}
El siguiente es un ejemplo, que arroja una excepción de división por cero y la capturamos en el bloque 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;
}
Porque estamos planteando una excepción de tipo const char*, así que mientras capturamos esta excepción, tenemos que usar const char * en el bloque catch. Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
Division by zero condition!
Excepciones estándar de C ++
C ++ proporciona una lista de excepciones estándar definidas en <exception>que podemos utilizar en nuestros programas. Estos están organizados en una jerarquía de clases de padres e hijos que se muestra a continuación:
Aquí está la pequeña descripción de cada excepción mencionada en la jerarquía anterior:
No Señor | Excepción y descripción |
---|---|
1 | std::exception Una excepción y clase principal de todas las excepciones estándar de C ++. |
2 | std::bad_alloc Esto puede ser lanzado por new. |
3 | std::bad_cast Esto puede ser lanzado por dynamic_cast. |
4 | std::bad_exception Este es un dispositivo útil para manejar excepciones inesperadas en un programa C ++. |
5 | std::bad_typeid Esto puede ser lanzado por typeid. |
6 | std::logic_error Una excepción que teóricamente se puede detectar leyendo el código. |
7 | std::domain_error Esta es una excepción lanzada cuando se usa un dominio matemáticamente inválido. |
8 | std::invalid_argument Esto se produce debido a argumentos no válidos. |
9 | std::length_error Esto se lanza cuando se crea una cadena std :: demasiado grande. |
10 | std::out_of_range Esto puede ser lanzado por el método 'at', por ejemplo un std :: vector y std :: bitset <> :: operator [] (). |
11 | std::runtime_error Una excepción que teóricamente no se puede detectar leyendo el código. |
12 | std::overflow_error Esto se lanza si ocurre un desbordamiento matemático. |
13 | std::range_error Esto ocurre cuando intenta almacenar un valor que está fuera de rango. |
14 | std::underflow_error Esto se lanza si se produce un desbordamiento matemático. |
Definir nuevas excepciones
Puede definir sus propias excepciones heredando y anulando exceptionfuncionalidad de clase. A continuación se muestra el ejemplo, que muestra cómo puede usar la clase std :: exception para implementar su propia excepción de manera estándar:
#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
}
}
Esto produciría el siguiente resultado:
MyException caught
C++ Exception
Aquí, what()es un método público proporcionado por la clase de excepción y ha sido anulado por todas las clases de excepción secundarias. Esto devuelve la causa de una excepción.