2008-08-04 23 views
21

Las excepciones en C++ no necesitan ser capturadas (no hay errores de tiempo de compilación) por la función de llamada. Depende del criterio del desarrollador capturarlos utilizando try/catch (a diferencia de Java).Asegurando que las excepciones siempre son

¿Hay alguna forma de garantizar que las excepciones lanzadas siempre se capturen mediante try/catch mediante la función de llamada?

+1

El consenso sobre el enfoque de Procrustean de Java a las especificaciones de excepción es que está muy roto. –

Respuesta

23

Ver A Pragmatic Look at Exception Specifications por razones de por qué no.

La única forma en que puede "ayudar" con esto es documentar las excepciones que su función puede arrojar, por ejemplo, como un comentario en el archivo de encabezado que lo declara. Esto no se aplica por el compilador ni nada. Use revisiones de código para ese propósito.

0

O podría comenzar a lanzar excepciones críticas. Sin duda, una excepción de violación de acceso será capturar la atención de los usuarios.

+0

¿Qué, ora, es una excepción "crítica"? –

+0

Si ha leído más allá del período, es posible que haya notado que mencioné explícitamente uno. –

4

Fuera del alcance de su pregunta, por lo que debatí no publicar esto, pero en Java hay actualmente 2 tipos de excepciones, marcadas y sin marcar. La diferencia básica es que, al igual que en c[++], no tiene que atrapar una excepción sin marcar.

Para una buena referencia try this

0

¿Hay alguna manera se puede asegurar que las excepciones producidas siempre son capturados utilizando try/catch por el función que llama?

Me parece bastante divertido, que la multitud de Java - including myself - está tratando de evitar excepciones marcadas. Están intentando forzar su camino para verse obligados a atrapar Excepciones usando RuntimeExceptions.

2

Chris 'tiene probablemente la mejor respuesta a la pregunta pura:

Sin embargo, siento curiosidad por la raíz de la cuestión. Si el usuario debe siempre envuelve la llamada en un bloque try/catch, ¿debería la función llamada por el usuario emitir excepciones en primer lugar?

Esta es una pregunta difícil de responder sin más contexto con respecto a la base de código en cuestión. Disparando desde la cadera, creo que la mejor respuesta aquí es ajustar la función de modo que la interfaz pública recomendada (si no solo, dependiendo del estilo de excepción general del código) intente/capture para el usuario. Si solo está tratando de asegurarse de que no haya excepciones no controladas en su código, las pruebas unitarias y la revisión del código probablemente sean la mejor solución.

9

No debe usar una excepción aquí. Obviamente, este no es un caso excepcional si necesita estar esperándolo en cualquier lugar donde use esta función.

Una mejor solución sería obtener la función para devolver una instancia de algo como esto. En las compilaciones de depuración (suponiendo que los desarrolladores sigan las rutas de código que acaban de escribir), obtendrán una afirmación si olvidan comprobar si la operación tuvo éxito o no.

class SearchResult 
{ 
    private: 
    ResultType result_; 
    bool succeeded_; 
    bool succeessChecked_; 

    public: 
    SearchResult(Result& result, bool succeeded) 
     : result_(result) 
     , succeeded_(succeeded) 
     , successChecked_(false) 
    { 
    } 

    ~SearchResult() 
    { 
     ASSERT(successChecked_); 
    } 

    ResultType& Result() { return result_; } 
    bool Succeeded() { successChecked_ = true; return succeeded_; } 
} 
+0

+1 a eso. Si espera algún resultado, no debe devolverse en forma de excepción. – macbirdie

+0

GCC al menos tiene un atributo de función para requerir el manejo del valor de retorno. Menos desordenado que este extra bool. –

+0

Muéstreme un ejemplo de alguien que no sea un charlatán o un pirata diciendo que las excepciones son * solo * para situaciones excepcionales. –

0

Había una vez un intento de añadir dynamic exception specifications a la firma de una función, pero dado que el lenguaje no podría cumplir su exactitud, no fueron posteriormente amortizadas.

En C++ 11 y hacia adelante, ahora tenemos el noexcept specifier.
Nuevamente, si la firma está marcada para arrojar, aún no es necesario que la persona que llama la maneje.


Dependiendo del contexto, puede garantizar que se maneje un comportamiento excepcional codificándolo en el sistema de tipos.

Ver:std::optional como parte de los fundamentos de la biblioteca.

Cuestiones relacionadas