Creo que la mejor manera de pensar en esto es en términos de estado del programa. No desea que una operación fallida dañe el estado del programa. This paper describe el concepto de "Seguridad de excepciones".
En general, primero debe decidir qué nivel de seguridad de excepción necesita una función para garantizar. Los niveles son
- básico Guarnantee
fuerte garantía
- nothrow Garantizar
la garantía básica simplemente significa que en la cara de una excepción o cualquier otro error, no hay recursos se filtró, la fuerte la garantía dice que el estado del programa se revierte a antes de la excepción, y los métodos de nothrow nunca arrojan excepciones.
Personalmente uso excepciones cuando se produce una falla imprevista en el tiempo de ejecución. Inesperado significa para mí que tal falla no debería ocurrir en el curso normal de las operaciones. Tiempo de ejecución significa que el error se debe al estado de algún componente externo fuera de mi control, en lugar de a errores lógicos de mi parte. Uso ASSERT() para detectar errores de lógica, y utilizo los valores de retorno booleanos para los errores esperados.
¿Por qué? ASSERT no está compilado en el código de publicación, por lo que no agobío a mis usuarios con la comprobación de errores de mis propios fallos. Para eso están las pruebas unitarias y ASSERTS. Booleanos porque lanzar una excepción puede dar el mensaje incorrecto. Las excepciones también pueden ser costosas. Si lanzo excepciones en el curso normal de la ejecución de la aplicación, no puedo usar la excelente excepción de "Catch on throw" del depurador de MS Visual Studio, donde puedo hacer que el depurador rompa un programa en el punto en que es. lanzado, en lugar de la opción predeterminada de solo detenerse en excepciones no controladas (bloqueadas).
Para ver una técnica de C++ para la Garantía básica, google "RAII" (Adquisición de recursos es inicialización). Es una técnica donde envuelve un recurso en un objeto cuyo constructor asigna el recurso y cuyo destructor libera el recurso. Como las excepciones de C++ desenrollan la pila, garantiza que los recursos se liberen frente a las excepciones. Puede usar esta técnica para revertir el estado del programa frente a una excepción. Simplemente agregue un método "Commit" a un objeto, y si un objeto no se compromete antes de que se destruya, ejecute la operación "Rollback" que restablece el estado del programa en el destructor.
+1: Y, una excepción solo se puede manejar cuando una función contiene estrategias alternativas para hacer algo. –
Creo que capturar una excepción para producir un registro útil, con más contexto que el lanzamiento inicial, puede ser útil a veces. Después de eso, vuelva a lanzarlo si no puede manejar la excepción. – extraneon
"con más información" es la clave. Simplemente el registro, sin información adicional, debe esperar al nivel superior. –