sábado, 19 de julio de 2025

Programando en C++ no. 5 (manejo de excepciones)

El manejo de excepciones nos ayuda a que el flujo normal de nuestros programas no se vea interrumpido. C++ tiene mecanismos similares a lenguajes como Java y/o C# para realizar esta tarea.

Una excepción ocurre cuando hay un problema en alguna instrucción de nuestro programa, ya sea por que accedemos a una variable sin asignación de valor y que de por resultado un null. Un acceso a un método en un momento inoportuno. Una conversión numérica que no cumple las condiciones adecuadas. Acceder a un elemento que no existe en un arreglo o matriz.

Nosotros podríamos provocar una excepción con toda intencionalidad. Veamos un ejemplo:

excepcion.cpp

#include <iostream>

int main() {
  try {
    throw 0.0;
  }
  catch(double ex){
    std::cout << "Excepcion de tipo double: " << ex << std::endl;
  }
}

Compilamos y ejecutamos:

$ g++ excepcion.cpp -o excepcion.exe
$ excepcion.exe

¿Qué queremos decir en este programa?

El bloque ``try-catch`` se encargará de lanzar (throw) una excepción para luego cacharla (catch). En este caso provocamos la excepción que es un valor 0.0 (tipo double) y la excepción deberá ser del mismo tipo.

En otras palabras:

  • try: define el código a probar, es decir, es el cuerpo del código donde puede ocurrir una excepción.
  • throw: activa o lanza una excepción. 
  • catch: maneja o atrapa el error.

Veamos las siguientes excepciones hechas en Java:

try{
    int divide = 2/0;
}catch(ArithmeticException ex){
    ex.printStackTrace();
}


int[] arreglo = {1,2,3};
try{
    int numero = arreglo[3];
}
catch(ArrayIndexOutOfBoundsException ex){
    ex.printStackTrace();
}
catch(Exception ex){
    ex.printStackTrace();
}


try{
    int entero = Integer.parseInt("23f");
}catch(NumberFormatException ex){
    ex.printStackTrace();
}


String cadena = null;
try{
    boolean vacio = cadena.isEmpty();
}catch(NullPointerException ex){
    ex.printStackTrace();
}

Tipos de excepciones que vemos:

  • ArithmeticException: cuando tratamos de hacer una operación aritmética inválida. En este caso una división por cero. 
  • ArrayIndexOutOfBoundsException: al tratar de acceder a un índice inexistente de un arreglo. 
  • NumberFormatException: intentar convertir una cadena a número, pero la cadena no cumple el formato numérico. 
  • NullPointerException: acceder a un elemento null.

El código equivalente en C++ sería algo como esto:

excepciones.cpp

#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>

int main() {
    // División por cero simulada
    try {
        int divisor = 0;
        if (divisor == 0) throw std::runtime_error("División por cero detectada.");
        int divide = 2 / divisor;
        std::cout << "Resultado: " << divide << std::endl;
    } catch (const std::exception& ex) {
        std::cerr << "[División] Excepción: " << ex.what() << std::endl;
    }

    // Acceso fuera de los límites del arreglo
    try {
        std::vector<int> arreglo = {1, 2, 3};
        int numero = arreglo.at(3); // índice fuera de rango
        std::cout << "Número: " << numero << std::endl;
    } catch (const std::out_of_range& ex) {
        std::cerr << "[Arreglo] Excepción: " << ex.what() << std::endl;
    } catch (...) {
        std::cerr << "[Arreglo] Otra excepción inesperada." << std::endl;
    }

    // Conversión inválida de cadena a entero
    try {
        std::string texto = "f23f";
        int numero = std::stoi(texto);
        std::cout << "Número convertido: " << numero << std::endl;
    } catch (const std::invalid_argument& ex) {
        std::cerr << "[Conversión] Excepción: " << ex.what() << std::endl;
    }

    // Puntero nulo accediendo a método
    try {
        std::string* cadena = nullptr;
        if (!cadena) throw std::runtime_error("Cadena nula.");
        bool vacio = cadena->empty();
        std::cout << "¿Está vacía?: " << std::boolalpha << vacio << std::endl;
    } catch (const std::exception& ex) {
        std::cerr << "[Cadena nula] Excepción: " << ex.what() << std::endl;
    }

    return 0;
}

Compilamos y ejecutamos:

$ g++ excepciones.cpp -o excepciones.exe
$ excepciones.exe

Salida:

[Divisi├│n] Excepci├│n: Divisi├│n por cero detectada.
[Arreglo] Excepci├│n: vector::_M_range_check: __n (which is 3) >= this->size() (which is 3)
[Conversi├│n] Excepci├│n: stoi
[Cadena nula] Excepci├│n: Cadena nula.

¡Hemos visto como crear excepciones en C++!

Continuaremos con este tema en próximas entregas sobre este lenguaje.

Enlaces:

https://codemonkeyjunior.blogspot.com/2024/06/hace-tiempo-vimos-como-crear-un.html
https://hektorprofe.github.io/cpp/13-manejo-excepciones/
https://isocpp.org/wiki/faq/exceptions
https://www.w3schools.com/cpp/cpp_exceptions.asp

No hay comentarios:

Publicar un comentario

Kubernetes en un vistazo

Continuamos con esta serie de entregas sobre Docker y Kubernetes Según la documentación oficial Kubernetes (k8s) es una plataforma de...

Etiquetas

Archivo del blog