Una excepción en C++ es un mecanismo que permite manejar errores o situaciones inesperadas durante la ejecución de un programa.
Cuando ocurre una excepción:
- Puede ser capturada por un bloque
try-catch
- Si no es capturada, pasa a la función que invocó a la que genero el error
Si no hay un bloque try-catch que capture la excepción, esta va “subiendo”. Si nadie la gestiona, la excepción llegará a la función principal (lo normal es que el programa termine abruptamente).
Las excepciones en C++ se lanzan mediante objetos, que pueden ser de cualquier tipo, aunque es común lanzar objetos de tipos específicos. (como std::runtime_error
o std::logic_error
).
Lanzar una excepción
En C++, podemos lanzar una excepción utilizando la palabra clave throw
. Esto nos permite indicar que ha ocurrido un error específico.
#include <stdexcept>
throw std::runtime_error("Ocurrió un error");
En este ejemplo, lanzamos una excepción de tipo std::runtime_error
con un mensaje de error.
Este mensaje puede utilizarse luego en el bloque catch
para identificar y manejar el error.
Excepciones predefinidas
En C++, existen varios tipos de excepciones predefinidas en la biblioteca estándar que permiten manejar errores comunes. Aquí algunos ejemplos:
std::runtime_error
Indica errores durante la ejecución, como fallos en operaciones de E/S o problemas de lógica inesperados.
throw std::runtime_error("Error en tiempo de ejecución");
std::logic_error
Señala errores de lógica en el programa, como condiciones de argumento incorrectas.
throw std::logic_error("Error lógico en la aplicación");
std::out_of_range
Se lanza cuando se intenta acceder a un elemento fuera del rango válido, por ejemplo, en un vector o array.
#include <vector>
std::vector<int> numeros = {1, 2, 3};
int valor = numeros.at(5); // Lanzará std::out_of_range
std::overflow_error
Indica un error de desbordamiento en cálculos aritméticos.
throw std::overflow_error("Desbordamiento aritmético");
std::underflow_error
Similar a std::overflow_error
, pero indica un desbordamiento negativo o bajo.
std::invalid_argument
Señala un argumento inválido en una función.
#include <stdexcept>
void establecerEdad(int edad) {
if (edad < 0) throw std::invalid_argument("La edad no puede ser negativa");
}
establecerEdad(-5); // Lanzará std::invalid_argument
std::bad_alloc
Se lanza cuando una operación de asignación de memoria falla.
try {
int* arr = new int[100000000000]; // Intento de asignar demasiada memoria
} catch (const std::bad_alloc& e) {
std::cout << "Error de asignación de memoria: " << e.what() << std::endl;
}
Estas son solo algunas de las excepciones comunes en C++. La biblioteca estándar incluye más excepciones específicas para diversas situaciones.
Crear excepciones personalizadas en C++
En C++ también es posible definir excepciones personalizadas creando clases que hereden de una clase base de excepción, como std::exception
.
#include <exception>
#include <string>
class MiExcepcion : public std::exception {
std::string mensaje;
public:
explicit MiExcepcion(const std::string& mensaje) : mensaje(mensaje) {}
const char* what() const noexcept override {
return mensaje.c_str();
}
};
Aquí, MiExcepcion
hereda de std::exception
y redefine el método what()
para proporcionar un mensaje de error personalizado.
Uso de una excepción personalizada
Podemos utilizar nuestra clase de excepción personalizada en un bloque try-catch
como cualquier otra excepción:
#include <iostream>
int main() {
try {
throw MiExcepcion("Error en mi aplicación personalizada");
} catch (const MiExcepcion& e) {
std::cout << "Excepción personalizada capturada: " << e.what() << std::endl;
}
return 0;
}
En este caso, el mensaje de error de MiExcepcion
se imprimirá en la consola.