destructores constructores c++ exception-handling destructor

constructores - Excepción en Destructor C++



constructores y destructores c++ pdf (2)

En su ejemplo, A() construye una variable temporal para A y la destruye inmediatamente. Por lo tanto, throw 10; nunca se ejecuta.

La instrucción throw que tiene lugar está en el destructor para A Al ejecutar A::~A() , el programa no se desenrolla (es decir, limpiando el estado de una excepción) en ese punto. Ver "Destructors that throw" por ejemplo.

Soy muy consciente del hecho de que no se debe lanzar ninguna excepción en destructor.

Pero como parte de mi control sobre este concepto, codifiqué este ejemplo:

#include <iostream> using namespace std; class A { private: int i; public: A() { i = 10; } ~A() { throw 30; } }; int main(){ try{ A(); throw 10; } catch (int i){ cout << i << endl; cout << "exception caught" << endl; } }

Según entiendo, este programa debe finalizar llamando a std :: terminate (), ya que habrá dos excepciones al mismo tiempo. Pero, este programa está dando el siguiente resultado:

30 exception caught

¿Alguien puede por favor explicarme la lógica detrás de esto sobre por qué esto no termina?


std::terminate se invocará si se produce una excepción durante el desenrollado de la pila . Eso significa que si se invoca una excepción mientras se maneja otra excepción , se llamará a std::terminate .

En su ejemplo, eso no sucede - A(); construirá y destruirá inmediatamente una instancia de A El throw 30 será atrapado correctamente.

Cambiando tu código a:

int main(){ try{ A a; // begin `a` lifetime throw 10; // | throw #0 // | end `a` lifetime // throw #1 } catch(int i){ cout<<i<<endl; cout<<"exception caught"<<endl; } }

garantizará que std::terminate se llamará. En este caso, a se destruirá y lanzará mientras se está manejando otra excepción .

ejemplo de coliru en vivo

Información Adicional:

Tenga en cuenta que en C ++ 11 y superior , su fragmento de código llamará a std::terminate y le proporcionará una advertencia:

main.cpp: en destructor ''A :: ~ A ()'':

main.cpp: 16: 15: warning: throw siempre llamará a terminate () [-Wterminate]

throw 30; ^~

main.cpp: 16: 15: nota: en C ++ 11 los destructores están por defecto en noexcept

finalizar llamada después de lanzar una instancia de ''int''

bash: línea 7: 1505 Aborted (core dumped) ./a.out

Como se ve en la salida del compilador, dado que los destructores C ++ 11 son implícitamente noexcept(true) . Si desea evitar este comportamiento, simplemente puede marcarlos como noexcept(false) . Ejemplo:

~A() noexcept(false) { throw 30; }

ejemplo en vivo en coliru