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

Claude Code: un nuevo enfoque de la programación por pares

Claude Code es una herramienta de inteligencia artificial creada por Anthropic que funciona directamente en la terminal. Sirve para acele...

Etiquetas

Archivo del blog