Excepciones
Last updated
Last updated
En la programación, las excepciones son situaciones inesperadas o errores que ocurren durante la ejecución de un programa. C++ proporciona un mecanismo para manejar estas excepciones, permitiendo al programador capturar y manejar los errores de manera controlada. En este post, exploraremos el concepto de excepciones en C++ y cómo se utilizan para el manejo de errores.
Las excepciones en C++ son objetos que se lanzan cuando se produce un error o una situación excepcional durante la ejecución de un programa. Estas excepciones se pueden lanzar en cualquier parte del código y se pueden capturar y manejar en bloques específicos.
Para lanzar una excepción en C++, se utiliza la palabra clave throw
, seguida de un objeto que representa la excepción. Por ejemplo:
En este ejemplo, se lanza una excepción de tipo MiExcepcion
con un mensaje de error específico.
Para capturar y manejar una excepción en C++, se utiliza la estructura try-catch
. El bloque try
se utiliza para envolver el código que puede lanzar una excepción, mientras que el bloque catch
se utiliza para capturar y manejar la excepción lanzada.
La sintaxis básica de try-catch
en C++ es la siguiente:
En este ejemplo, el bloque try
contiene el código que puede lanzar una excepción. Si se produce una excepción del tipo especificado en el bloque catch
, el control del programa se transfiere al bloque catch
correspondiente, donde se puede manejar la excepción de acuerdo a los requerimientos del programa.
C++ proporciona una serie de clases de excepciones predefinidas que se pueden utilizar para representar diferentes tipos de errores. Algunas de las clases de excepciones más comunes son:
std::exception
: Clase base para todas las excepciones.
std::runtime_error
: Excepción que representa errores en tiempo de ejecución.
std::logic_error
: Excepción que representa errores lógicos o de programación.
std::out_of_range
: Excepción que se lanza cuando se intenta acceder a un índice fuera de rango.
std::bad_alloc
: Excepción que se lanza cuando hay problemas de asignación de memoria dinámica.
Estas clases de excepciones predefinidas se pueden utilizar tal como están o se pueden heredar para crear clases de excepciones personalizadas que se ajusten a las necesidades específicas del programa.
La jerarquía de excepciones en C++ se refiere a la organización de las excepciones en una estructura de árbol, donde las excepciones más generales se encuentran en la parte superior y las más específicas se encuentran en niveles inferiores. Esta jerarquía permite capturar y manejar diferentes tipos de excepciones de manera más precisa.
La ventaja de tener una jerarquía de excepciones es que podemos capturar y manejar excepciones de manera más granular. Podemos capturar excepciones específicas en primer lugar y luego capturar excepciones más generales si es necesario. Esto nos permite tomar acciones diferentes según el tipo de error que se haya producido.
Si hay una excepción de mayor jerarquia antes de cualquier otra, terminará siempre por entar en ese catch
, ya que engloba todos lo errores.
Por ejemplo:
En este ejemplo, se capturan excepciones específicas primero, como std::invalid_argument
y std::runtime_error
, y luego se captura una excepción más genérica std::exception
en caso de que no se haya capturado ninguna excepción específica.
La jerarquía de excepciones en C++ nos permite estructurar nuestro código de manejo de errores de manera más organizada y responder adecuadamente a diferentes situaciones de error.
Aunque C++ proporciona excepciones predefinidas, también es posible crear excepciones personalizadas para abordar situaciones específicas y mejorar la legibilidad y el mantenimiento del código.
En C++, se pueden crear excepciones personalizadas mediante la creación de una clase que herede de la clase base std::exception
o de una de sus subclases derivadas, como std::runtime_error
o std::logic_error
.
En este ejemplo, hemos creado una excepción personalizada llamada MiExcepcion
que hereda de std::exception
. La función what()
se sobrescribe para devolver el mensaje de la excepción cuando se produce un error.
En la cabecera de la función what()
, el throw() e
una especificación opcional y su objetivo es indicar que la función what()
no lanzará excepciones durante su ejecución.
En el caso de que qieras crear un tipo de excepcion que requeira de argumentos tendras que crear el constructor y destructor:
A la hora de crear el mensaje
es necesario hacerlo en el constructor por que si intenamtos hacerlo en la funcion what()
esta devovlera un puntero que se destruira nada mas terminar la funcion, pro lo que devlvera basura.
En el caso de que en el erro tan solo queiras devovelr el valor paso al cosntrutor el cosntrucotre se puede declarar de la siguiente manera:
Por otro lado en el caso de que quieras devolver una excepcion con disitnto tipos e datos como integers y strings hay que utilizar el tipo de dato std::ostringstream
y despues trasformal a string:
En este ejemplo, creamos un objeto std::ostringstream
llamado oss
. Luego, utilizamos el operador <<
para concatenar datos en el objeto oss
. Finalmente, obtenemos la cadena resultante utilizando oss.str()
y lo devolvemos utilizando c_str()
para transformarlo a un const char*
.
std::ostringstream
es una clase de la biblioteca estándar de C++ que se utiliza para construir y manipular cadenas de caracteres, de manera similar a cómo se trabaja con std::cout
para mostrar datos en la salida estándar.
Una vez que se ha creado una excepción personalizada, se puede lanzar utilizando la palabra clave throw
. A continuación, se muestra un ejemplo de cómo lanzar y capturar una excepción personalizada:
En este ejemplo, se intenta realizar una división por cero en la función dividir()
. Si ocurre una excepción de tipo MiExcepcion
, se captura en el bloque catch
correspondiente y se muestra el mensaje de la excepción utilizando la función what()
.