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 .
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;
}