2011-07-23 14 views
25

¿Es correcto usar throw new FoobarException(Baz argument); o throw FoobarException(Baz argument);?C++: lanzando excepciones, use 'nuevo' o no?

Al capturar Siempre uso catch(FoobarException& e) "por las dudas" pero nunca pude encontrar una respuesta sólida si tenía que usar algo nuevo o no en C++ (Java definitivamente) o si era solo una preferencia del programador.

+2

No creo que atrape si lanzas por puntero e intentas atrapar por referencia, ¿o sí? –

+2

Si usa nuevo, 'catch (FoobarException &)' no capturará su objeto. nuevo crea punteros. –

Respuesta

33

Las excepciones en C++ deben arrojarse por valor y capturarse por referencia.

Así que esta es la forma correcta:

try 
{ 
    throw FoobarException(argument); 
} 
catch(const FoobarException &ex) 
{ 
    cout << ex.what() << endl; 
} 

No arrojar una excepción creada con el nuevo, ya que es responsable de eliminar no está bien definido. Además, realizar asignaciones durante el manejo de errores puede arrojar otra excepción, oscureciendo el problema original.

No tiene que atrapar por referencia de constricción (no const funcionará bien), pero me gusta hacerlo de todos modos. Sin embargo, siempre debe hacer referencia (no por valor) para atrapar la excepción de forma polimórfica. Si no lo hace, el tipo de la excepción se puede dividir.

+0

¿Por qué la excepción siempre debe captarse por referencia, no por valor? ¿Estás hablando sobre el problema de corte de objetos debido a pasar el objeto derivado por valor a un método que espera el argumento del objeto de la clase base? – Destructor

7

a menos que exista algún requisito especial para no hacerlo, siempre arrojo por valor y capturo por const de referencia. Esto se debe a que el new también podría lanzar una excepción, durante el manejo de errores, es mejor evitar cosas que pueden causar excepciones.

+0

Correcto, lanzar una excepción mientras está activa otra excepción está esencialmente prohibido (creo que es UB), por lo que el estándar 'new' está fuera. Podrías usar alguna asignación que no sea tirada si realmente fueras necesario, pero eso sigue siendo una locura :-) –

+1

Mis 2c: solo para agregar al sabio consejo de @KerrekSB, en realidad es un comportamiento definido (ver http: //en.cppreference) .com/w/cpp/error/terminate). El enlace mencionado anteriormente también apunta a una serie de otras cosas que es mejor evitar (como lanzar excepciones de destructores, porque entonces puede terminar levantando excepciones mientras se desenrolla la pila para una excepción lanzada previamente). – Rob

Cuestiones relacionadas