AnyCompiler

Exceptions y Manejo de Errores

Una función que encuentra un error que no puede manejar localmente puede lanzar una exception — la ejecución inmediatamente desenrolla la call stack hasta encontrar un catch block que coincida. Un throw sin ningún catch que coincida en ningún lado termina el programa.

#include <iostream>
#include <stdexcept>
using namespace std;

double divide(double a, double b) {
    if (b == 0) {
        throw runtime_error("cannot divide by zero");
    }
    return a / b;
}

int main() {
    try {
        cout << divide(10, 2) << endl;
        cout << divide(10, 0) << endl;
    } catch (const runtime_error& e) {
        cout << "Error: " << e.what() << endl;
    }
    return 0;
}
Output
5
Error: cannot divide by zero

Fíjate que divide(10, 2) imprime su resultado normalmente, pero divide(10, 0) lanza antes de poder retornar — la ejecución salta directo al catch block, saltándose por completo el resto del try block. Mientras la stack se desenrolla pasando por cualquier object RAII en el camino, sus destructors igual se ejecutan normalmente, así que los recursos se limpian incluso cuando una exception corta una función a mitad de camino.

Esa es la base de C++: references y pointers para acceso flexible sin copiar siempre, RAII para una limpieza determinista de recursos sin recolector de basura, classes con virtual dispatch para polymorphism, y templates para código genérico en tiempo de compilación. Desde aquí, el mejor siguiente paso es practicar — elige un programa pequeño y constrúyelo, prestando mucha atención a quién posee cada recurso y cuándo se limpia.

Practice exercise

Escribe una función safeDivide(double a, double b) que lance un runtime_error("cannot divide by zero") si b es 0, de lo contrario devuelva a / b. Llámala con (10, 0) dentro de un try/catch, e imprime el mensaje de la exception capturada.

← Smart PointersMás lecciones próximamente