2012-01-28 23 views
6

Considere el siguiente código:Destructor no llama cuando se produce una excepción

#include <iostream> 
using namespace std; 

class Test { 
    static int count; 
    int id; 
public: 
    Test() { 
    count++; 
    id = count; 
    cout << "Constructing object number " << id << endl; 
    if(id == 4) 
     throw 4; 
    } 
    ~Test() { cout << "Destructing object number " << id << endl; } 
}; 

int Test::count = 0; 

int main() { 
    try { 
    Test array[5]; 
    } catch(int i) { 
    cout << "Caught " << i << endl; 
    } 
} 

El código anterior produce la siguiente salida:

Constructing object number 1 
Constructing object number 2 
Constructing object number 3 
Constructing object number 4 
Destructing object number 3 
Destructing object number 2 
Destructing object number 1 
Caught 4 

pensé destructores siempre fueron llamados cuando los objetos se hacen fuera de alcance , incluso cuando se lanzan excepciones. ¿Por qué no se llama a uno de los destructores de las instancias Test en este caso?

+0

He editado su pregunta en algo más adecuado para Stack Overflow. Por favor, siga [las pautas de la pregunta] (http://stackoverflow.com/questions/how-to-ask) para referencia futura o su pregunta puede ser downvoted/closed. –

Respuesta

8

Usted está creando una serie de 5Test objetos, sino que lanza una excepción después de crear 3completos objetos, se produce la excepción, mientras que en el constructor del objeto 4 XX. La construcción del objeto 4 th no está completa hasta que se alcanza el corchete de cierre del constructor.

La pila desenrolla llamando destructor para aquellos 3 objetos construidos por completo en el orden inverso en el que fueron creados, ya que el 4 XIX y XX 5 objeto nunca se construyeron al destructor para ellos nunca es llamado.

La regla de excepción es:
Una vez que se lanza una excepción, se invocarán los destructores para todos los objetos completamente creados dentro de ese ámbito.
Un objeto completamente creado es aquel cuyo constructor ha sido llamado limpiamente sin ninguna excepción.

+0

Este [artículo del gurú de la semana (# 66)] (http://www.gotw.ca/gotw/066.htm) es especialmente relevante para esta situación. –

+0

off by one - solo hay 3 objetos completamente construidos, por lo que solo se llaman 3 destructores. –

+0

@ChrisDodd: Oh bien descubierto. Me equivoqué leyendo los rastros. –

3

En vez de escribiendo la instrucción cout después de id = cuentan como se menciona a continuación: -

id = count; 
    cout << "Constructing object number " << id << endl; 
    if(id == 4) 
    throw 4; 

que debería haber escrito después de la sentencia throw. Eso le hubiera dado una mejor imagen de de lo que sucedió. De esta manera: -

Test() { 
count++; 
id = count; 
if(id == 4) 
    throw 4; 
cout << "Constructing object number " << id << endl; 
    } 

La O/P hubiera sido: - Construir número de objetos 1 Construir número objeto 2 objeto Construir número 3 Destructing objeto número 3 Destructing objeto número 2 número de objeto Destructing 1 Atrapado 4

Cuestiones relacionadas