2010-02-05 8 views

Respuesta

48

De § 3.6.3 de la norma C++ 03:

Destructores (12.4) para objetos inicializados de duración de almacenamiento estático (declarados en alcance de bloque o en ámbito de espacio de nombres) son llamados como resultado de regresar de main y como resultado de la llamada de salida (18.3). Estos objetos se destruyen en el orden inverso de la finalización de su constructor o de la finalización de su inicialización dinámica. Si un objeto se inicializa estáticamente, el objeto se destruye en el mismo orden que si el objeto se hubiera inicializado dinámicamente. Para un objeto de matriz o tipo de clase, todos los subobjetos de ese objeto se destruyen antes de que se destruya cualquier objeto local con duración de almacenamiento estático inicializada durante la construcción de los subobjetos.

Además, § 9.4.2 7 estados:

miembros de datos estáticos se inicializan y destruyeron exactamente igual que los objetos no locales (3.6.2, 3.6.3).

Sin embargo, si un destructor no tiene un comportamiento observable, es posible que no se invoque. Terry Mahaffey detalla esto en su answer to "Is a C++ destructor guaranteed not to be called until the end of the block?".

+1

Solo como una observación: Visual C++ 2010 parece ignorar este estándar (entre otros). No pude atrapar el punto de interrupción en un destructor de prueba. Ver: http://pastebin.com/sCMFYhzZ – progician

+1

@progician: ¿el destructor tiene un comportamiento observable? Es posible que VC++ '10 haya permitido eludir la llamada al destructor. Intente imprimir un mensaje y luego leer la entrada, o abrir un archivo y escribir en el destructor. – outis

+0

... Por supuesto, no me sorprendería demasiado si VC++ ignorara el estándar. – outis

3

En algún lugar después de "principal"

(no se puede saber o confiar en el orden exacto en el que se les llama)

+5

Sucede _antes de que 'std :: cout' se destruya. Es decir. puedes imprimir cosas allí. – MSalters

+0

@MSalters Supongo que es solo un detalle de su implementación particular y/o el orden en el que declaró sus objetos relativos a 'cout' o la primera llamada que invoca a su constructor (por ejemplo' operator <<() '). Dudo que esté garantizado, en cuyo caso, volvería a enfatizar el "no puedo confiar" en esta respuesta. –

+1

@underscore_d: No, definitivamente es una garantía. Es posible porque la Biblioteca estándar es especial/conocida para la implementación. – MSalters