Entiendo muy mal el manejo de excepciones (es decir, cómo personalizar las declaraciones de lanzamiento, intento y captura para mis propios fines).
Por ejemplo, he definido una función de la siguiente manera: int compare(int a, int b){...}
Me gustaría que la función arroje una excepción con algún mensaje cuando ao b sea negativo.
¿Cómo debería abordar esto en la definición de la función?
c++
exception-handling
Terry Li
fuente
fuente
unsigned int
los parámetros en la firma de su función. Por otra parte, soy de la escuela en la que solo debes lanzar y atrapar excepciones para cosas que son realmente excepcionales.throw()
especificaciones de excepción en las funciones.Respuestas:
Sencillo:
La Biblioteca estándar viene con una buena colección de objetos de excepción incorporados que puede lanzar. Tenga en cuenta que siempre debe arrojar por valor y capturar por referencia:
Puede tener varias instrucciones catch () después de cada intento, por lo que puede manejar diferentes tipos de excepción por separado si lo desea.
También puede volver a lanzar excepciones:
Y para detectar excepciones independientemente del tipo:
fuente
throw;
( volver a lanzar el objeto original y preservar su tipo) en lugar dethrow e;
(arrojar una copia del objeto capturado, posiblemente cambiando su tipo).Simplemente agregue
throw
donde sea necesario ytry
bloquee a la persona que llama que maneja el error. Por convención, solo debe arrojar cosas que se derivanstd::exception
, por lo tanto, incluya<stdexcept>
primero.Además, busque en Boost.Exception .
fuente
Aunque esta pregunta es bastante antigua y ya ha sido respondida, solo quiero agregar una nota sobre cómo hacer un manejo adecuado de excepciones en C ++ 11:
Uso
std::nested_exception
ystd::throw_with_nested
Se describe en StackOverflow aquí y aquí , cómo puede obtener un seguimiento de sus excepciones dentro de su código sin necesidad de un depurador o un registro engorroso, simplemente escribiendo un controlador de excepciones adecuado que arroje excepciones anidadas.
Como puede hacer esto con cualquier clase de excepción derivada, ¡puede agregar mucha información a dicha traza inversa! También puede echar un vistazo a mi MWE en GitHub , donde una traza inversa se vería así:
fuente
Puede definir un mensaje para lanzar cuando se produce un cierto error:
o podrías definirlo así:
Por lo general, tendría un
try ... catch
bloque como este:fuente
Quería AGREGAR a las otras respuestas descritas aquí una nota adicional, en el caso de excepciones personalizadas .
En el caso de que cree su propia excepción personalizada, que se deriva de
std::exception
, cuando captura "todos los tipos de excepciones posibles", siempre debe comenzar lascatch
cláusulas con el tipo de excepción "más derivado" que se puede detectar. Vea el ejemplo (de lo que NO debe hacer):NOTA:
0) El orden correcto debe ser al revés, es decir, primero usted,
catch (const MyException& e)
seguido decatch (const std::exception& e)
.1) Como puede ver, cuando ejecuta el programa tal como está, se ejecutará la primera cláusula catch (que probablemente es lo que NO quería en primer lugar).
2) Aunque el tipo capturado en la primera cláusula catch es de tipo
std::exception
,what()
se llamará a la versión "adecuada" , porque se captura por referencia (cambie al menos elstd::exception
tipo de argumento capturado por valor) y experimentará el fenómenos de "corte de objetos" en acción).3) En caso de que "algún código debido al hecho de que se lanzó la excepción XXX ..." hace cosas importantes CON RESPECTO al tipo de excepción, hay un mal comportamiento de su código aquí.
4) Esto también es relevante si los objetos capturados eran objetos "normales" como:
class Base{};
yclass Derived : public Base {}
...5)
g++ 7.3.0
en Ubuntu 18.04.1 produce una advertencia que indica el problema mencionado:Una vez más , diré que esta respuesta es solo para AGREGAR a las otras respuestas descritas aquí (pensé que vale la pena mencionar este punto, pero no pude describirlo en un comentario).
fuente