c++ - son - try catch++
Diferencia: std:: runtime_error vs std:: exception() (2)
¿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?
std :: exception debe considerarse (tenga en cuenta lo considerado) la base abstracta de la jerarquía de excepciones 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 otro lado 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";
}
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
, destinada a lanzarse en caso de varios errores de tiempo de ejecución . 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 de tiempo de ejecución, como std::range_error
, std::overflow_error
etc. Puede definir sus propias clases de excepciones que descienden de std::runtime_error
, así como usted puede definir sus propias clases de excepción que descienden de std::exception
.
Al igual que std::runtime_error
, la biblioteca estándar contiene std::logic_error
, que 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)
capturará todas las excepciones del subárbol std::runtime_error
, permitiendo que todos los demás pasen (y vuele más arriba en la pila de llamadas).
PS Diseñar una jerarquía de clase de excepción útil (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 Linux vs Windows
Como Loki Astari y unixman83 anotaron en su respuesta y comentarios a continuación, el constructor de la clase de exception
no toma ningún argumento según el estándar de C ++. Microsoft C ++ tiene un constructor tomando argumentos en la clase de exception
, pero esto no es estándar. La clase runtime_error
tiene un constructor que toma argumentos ( char*
) en ambas plataformas, Windows y Linux. Para ser portátil, mejor use runtime_error
.
(Y recuerde, solo porque una especificación de su proyecto dice que su código no tiene que ejecutarse en Linux, eso no significa que nunca tenga que ejecutarse en Linux).