De acuerdo con this site es perfectamente útil para lanzar una cuerda o un número entero. Encuentro esto bastante limpio y fácil de entender. ¿Cuáles son las desventajas de throw "description of what happened"
en lugar de throw std::runtime_error("description of what happened")
?Excepciones a C++: ¿Por qué usar o extender std :: exception?
Respuesta
Ese sitio es estúpido, y enseña mal diseño.
Si se lanza int
o char*
, entonces tendrá que atraparlo usando int
o char*
solamente. Puede calificarlo con const
.
Si arroja std::runtime_error
, puede capturarlo usando std::runtime_error const &
, o su clase base std::exception const &
.
¿Qué tiene de bueno esto?
El bueno de esto es que si se arroja una excepción el uso de una clase que se deriva en última instancia std::exception
, entonces se puede escribir sólo UN catch
bloque que acepta la excepción, ya que std::exception const&
, independientemente de which derived class se utiliza para lanzar una excepción.
Aquí está un ejemplo:
void f(A & a)
{
if (!check_arg(a))
{
throw std::invalid_argument("invalid argument");
}
else if (!check_size(a))
{
throw std::length_error("invalid length");
}
//code
if(someCondition)
{
//assume your_own_defined_exception's ultimate base is std::exception
throw your_own_defined_exception("condition unsatisfied");
}
//...
}
Ahora la parte interesante:
try
{
f(a); //it can throw exception of at least 3 types!
}
catch(std::exception const &e) //all types can be caught by just one catch!
{
//handle this case
}
Lo bueno es que usted no es requiere escribir trescatch
bloques sólo porque f()
podría lanzar tres diferentes tipos de excepción. Usted puede escribir más de un catch
para manejarlos de manera diferente si eso lo beneficia de alguna manera. Pero el punto a tener en cuenta aquí es: no ¡un requisito!
En resumen, puede aprovechar la jerarquía de clases.
Principalmente porque cuando trabajas con otras personas tienes que acordar qué atrapar. Si trato de atrapar un const std::exception&
y arrojas const char*
, entonces no voy a atrapar tus cosas y podrían pasar cosas malas.
Realmente no importa qué tipo se tira y atrapa, siempre y cuando todos se apeguen a él. Supongo que std::exception
se elige sobre const char*
porque le permite poner más que solo una cadena en el objeto de excepción. Es simplemente más flexible.
Si hace que una regla en su código arroje excepciones solo derivadas de std :: exception, es más fácil capturarlas. En otras palabras, sólo puede tener una sola cláusula catch en std :: excepción:
catch (std::exception& e)
{
log_message(e);
throw;
}
Pero si usted no sigue esta regla, entonces al final tener que escribir cláusulas de captura cuando no tiene que hacerlo.
hay poco beneficio para atrapar y volver a lanzar en cada capa, solo use una cláusula 'catch' si realmente tiene algo que hacer (y en C++, con RAII, esto debería ser lo suficientemente raro) o para" tragarlo ". –
Me resulta útil para generar un seguimiento de pila para las excepciones que no se esperan. Ayuda a diagnosticar un error y hacer un seguimiento del origen de la excepción. – sashang
Estoy de acuerdo en que las pilas son útiles, sin embargo, hay dos aspectos negativos en su enfoque. Primero desordena el código, ya no es obvio cuando se debe tomar una acción * específica * en caso de excepción. En segundo lugar, es un cerdo de alto rendimiento, porque la implementación de la excepción de costo cero que utilizan los compiladores populares, como gcc o Clang, impone una dura penalización a los lanzamientos. Hay otras alternativas, y las encuentro mejores. El código específico de plataforma para capturar la pila en el punto de lanzamiento es uno; otra es utilizar RAII para registrar "notas" que se agregan a la excepción durante el desenrollado. –
Un punto adicional provocada por otras respuestas es esto -
Si se lanza un entero o una cadena y que se desea capturar una error específico no se puede. Debe capturar todas las excepciones "int" y luego comparar las que desea capturar, y luego volver a lanzar las que no esté preparado para tratar. Si heredas de la excepción, puedes atrapar la excepción específica que deseas manejar y aún así tener la ventaja de poder capturar std :: exception si quieres manejarlas todas.
- 1. C++ Excepciones; int o std :: excepción?
- 2. C++ Excepciones y herencia de std :: excepción
- 3. C++ Exception Handling
- 4. Diferencia: std :: runtime_error vs std :: exception()
- 5. catching std :: exception by reference?
- 6. ¿Cómo obtengo una descripción de error std :: exception cuando llamo a un dll C++ desde C#
- 7. ¿Por qué no se detectan mis excepciones de C++?
- 8. Forma correcta de heredar de std :: exception
- 9. ¿Por qué volver a lanzar excepciones?
- 10. ¿Debo derivar excepciones personalizadas de Exception o ApplicationException en .NET?
- 11. ¿Qué arrojar al lanzar excepciones de C++?
- 12. C++ excepciones, ¿qué() puede ser NULO?
- 13. ¿Por qué usar c cadenas en C++?
- 14. Excepciones personalizadas en C++
- 15. C++ obtiene la pila de llamadas de std :: exception
- 16. ¿Por qué extender la clase de excepción?
- 17. ¿Por qué usar div o ldiv en C/C++?
- 18. ¿Extender la biblioteca estándar de C++ por herencia?
- 19. ¿Por qué C++ std :: list :: clear() no llama a destructores?
- 20. ¿Por qué necesito std :: get_temporary_buffer?
- 21. ¿Por qué "except Exception" no captura SystemExit?
- 22. C# exception filter?
- 23. ¿Extender Backbone.sync a la sincronización por lotes?
- 24. ¿Por qué mi código compila con -fno-excepciones en Qt Creator cuando trato de usar excepciones?
- 25. finalizador C# throwing exception?
- 26. ¿Por qué debería uno usar std :: cadena sobre cadenas estilo c en C++?
- 27. C# ¿Por qué usar SuspendLayout()?
- 28. ¿Crear excepción personalizada o usar excepciones integradas?
- 29. ¿Por qué std :: type_info polymorphic?
- 30. Uso de la clase Exception en C#
Básicamente, naturalmente, permite que la herencia simplifique el diseño del manejo de errores. Muy elegante. Si defino mi propia clase de excepción y lo hago de esa manera, puedo producir los mismos resultados, ¿sí? –
@StevenLu Si obtiene su propia clase de excepción, reinventa la rueda y potencialmente descifra el código que depende de la captura de std :: exception. Si bien esto puede estar bien para sus proyectos personales, hace que su código sea difícil de distribuir a otros. El enfoque estándar es tener una jerarquía de excepciones específica de la aplicación que subclases 'std :: exception'. Por ejemplo, haga que todas sus excepciones sean subclases de 'StevenLuException', que es una subclase de' std :: exception'. – sfstewman
@StevenLu: si su clase de excepción deriva en última instancia de 'std :: exception', entonces sí, es un diseño elegante. Ver la * tercera * excepción llamada 'your_own_defined_exception' en mi código de ejemplo. Dije que tiene que derivarse de 'std :: exception' en última instancia. – Nawaz