¿Cuál es la diferencia entre std::runtime_error
y std::exception
? ¿Cuál es el uso apropiado para cada uno? ¿Por qué son diferentes en primer lugar?Diferencia: std :: runtime_error vs std :: exception()
Respuesta
std::exception
es la clase cuyo único propósito es servir como la clase base en la jerarquía de excepciones. No tiene otros usos. En otras palabras, conceptualmente es una clase abstracta (aunque no se define como clase abstracta en C++, significado del término).
std::runtime_error
es una clase más especializada, que desciende de std::exception
, destinado a ser lanzado en el caso de varios tiempo de ejecución errores. Tiene un doble propósito. Se puede lanzar solo, o puede servir como una clase base para varios tipos más especializados de excepciones de error en tiempo de ejecución, como std::range_error
, std::overflow_error
, etc. Puede definir sus propias clases de excepciones descendientes desde std::runtime_error
, así como también puede definir sus propias clases de excepciones que descienden de std::exception
.
Al igual que std::runtime_error
, la biblioteca estándar contiene std::logic_error
, también desciende de std::exception
.
El objetivo de tener esta jerarquía es dar al usuario la oportunidad de utilizar todo el poder del mecanismo de manejo de excepciones de C++. Como la cláusula 'catch' puede capturar excepciones polimórficas, el usuario puede escribir cláusulas 'catch' que pueden capturar tipos de excepción de un subárbol específico de la jerarquía de excepciones. Por ejemplo, catch (std::runtime_error& e)
captará todas las excepciones desde el subárbol std::runtime_error
, permitiendo que todos los demás pasen (y vuelen más arriba en la pila de llamadas).
P.S. Diseñar una jerarquía útil de clases de excepción (que le permita capturar solo los tipos de excepción que le interesan en cada punto de su código) es una tarea no trivial. Lo que se ve en la biblioteca estándar de C++ es un enfoque posible, ofrecido por los autores del lenguaje. Como puede ver, decidieron dividir todos los tipos de excepción en "errores de tiempo de ejecución" y "errores de lógica" y le permiten continuar desde allí con sus propios tipos de excepciones. Existen, por supuesto, formas alternativas de estructurar esa jerarquía, que podría ser más apropiada en su diseño.
Actualización: Portabilidad de Windows Linux vs
Como Loki Astari y unixman83 señaló en su respuesta y comentarios a continuación, el constructor de la clase exception
no toma ningún argumento según el estándar C++. Microsoft C++ tiene un constructor tomando argumentos en la clase exception
, pero esto no es estándar. La clase runtime_error
tiene un constructor tomando argumentos (char*
) en ambas plataformas, Windows y Linux. Para ser portátil, mejor uso runtime_error
.
(Y recuerde, sólo porque una especificación de su proyecto dice su código no tiene que ejecutar en Linux, esto no significa que no nunca se tiene que ejecutar en Linux.)
std :: excepción debe ser considera (tenga en cuenta lo considerado) la base abstracta de la jerarquía de excepción estándar. Esto se debe a que no hay un mecanismo para pasar en un mensaje específico (para hacerlo debe derivar y especializar qué()). No hay nada que le impida usar std :: exception y para aplicaciones simples puede ser todo lo que necesita.
std :: runtime_error por el contrario tiene constructores válidos que aceptan una cadena como un mensaje.Cuando lo que() se llama un puntero const char se devuelve que apunta a una cadena C que tiene la misma cadena que se pasó al constructor.
try
{
if (badThingHappened)
{
throw std::runtime_error("Something Bad happened here");
}
}
catch(std::exception const& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
Gracias por la respuesta Martin. Sin embargo, uso std :: exception() de la misma manera que describiste arriba. es decir, el constructor std :: exception() también puede tomar std :: string() o const char *. – sivabudh
No según el estándar. std :: exception tiene un constructor que no toma argumentos. Usar una versión que acepte std :: string o C-String no es portátil. –
Debido a Microsoft, me acostumbré a lanzar 'std :: exception (std :: string)'. Ahora me doy cuenta de que debo lanzar 'std :: runtime_error' si quiero que mi código funcione en Linux (GCC). – unixman83
- 1. Confundido sobre std :: runtime_error contra std :: logic_error
- 2. std :: runtime_error que falta en qt + MinGW
- 3. std :: cin.getline() vs. std :: cin
- 4. std :: mem_fun vs std :: mem_fn
- 5. catching std :: exception by reference?
- 6. std :: this_thread :: yield() vs std :: this_thread :: sleep_for()?
- 7. Rendimiento std :: strstr vs std :: string :: encontrar
- 8. std :: string :: longitud() vs. std :: string :: size()
- 9. arrojar nueva std :: excepción vs std :: excepción tiro
- 10. Excepciones a C++: ¿Por qué usar o extender std :: exception?
- 11. std :: list vs std :: vector iteration
- 12. Forma correcta de heredar de std :: exception
- 13. ¿std :: runtime_error copia la cadena pasada en el constructor?
- 14. ¿Cuál es la diferencia entre std :: set y std :: vector?
- 15. std :: size_t vs size_t vs std :: string :: size_type
- 16. std :: hash_set vs std :: unordered_set, ¿son lo mismo?
- 17. Rendimiento relativo de std :: vector vs. std :: list vs. std :: slist?
- 18. std :: string vs. char *
- 19. printf vs std :: cout
- 20. std :: vector vs normal array
- 21. ¿Hay alguna diferencia entre usar .begin() vs .end() para std :: inserter para std :: set?
- 22. std :: atomic | compare_exchange_weak vs. compare_exchange_strong
- 23. std :: stringstream y std :: ios :: binario
- 24. ¿Cuál es la diferencia entre std :: merge y std :: set_union?
- 25. ¿Cuál es la diferencia entre std :: valarray y std :: array
- 26. ¿Cuál es la diferencia entre std :: condition_variable y std :: condition_variable_any?
- 27. iterador avanzado para el std :: vector std :: advance VS operator +?
- 28. C++ obtiene la pila de llamadas de std :: exception
- 29. de compilación de error cuando se intenta heredar de std :: runtime_error
- 30. std :: vector versus std :: array en C++
gracias. gran respuesta. aunque me pregunto si alguna vez existe la necesidad de tener un tipo diferente de excepción ... solo un pensamiento. – sivabudh
Si hay una posibilidad de que se pueda volver a cubrir la excepción, entonces puede ser útil un tipo diferente de excepción, ya que podemos usar el mecanismo de manejo de excepciones para dirigir la excepción al controlador que intentará corregir el problema. Si no hay posibilidad de recuperación, una de las excepciones estándar está bien. –
Solo como un lado: no hay ninguna regla, en ninguna parte, que te obligue a derivar de 'std :: exception'. Claro, todas las cosas 'std' arrojan clases derivadas de eso, pero no hay absolutamente ninguna razón para lanzar solo objetos derivados' std :: exception'. – rubenvb