2010-02-03 14 views
12

Supongamos que tengo la siguiente snipplet:C++ y destructor llamada de función para

Foo foo; 
.... 
return bar(); 

Ahora, ¿el estándar de C++ me garantiza que la barra() será llamada antes de foo :: ~ Foo()? ¿O es esta la elección del compilador/implementación?

Gracias!

+0

¿Qué dice tu libro de C++ sobre el tema? –

+2

¿De qué es este libro del que hablas? ¿Es como desbordamiento de pila, pero editado, y puesto en papel? – anon

Respuesta

15

Es un comportamiento garantizado. La ejecución real se desenrolla de la siguiente manera:

0: enter block (scope) 
1: Foo::Foo() 
2. evaluation of bar(); as expression in return statement 
3. save result of the expression as value returned from function 
4. finalize return statement to leave function to its caller (request exit from current scope) 
5: exit block (scope) with call to Foo::~Foo() 

Estas son algunas referencias de la norma:

  • qué programa de garantías de ejecución, por lo general

1,9 Ejecución del programa

10 Una instancia de cada objeto con duración de almacenamiento automático (3.7.2) es asociado a cada entrada en su bloque .

  • El foo tiene una duración de almacenamiento automático y:

3.7.2 almacenamiento automático de duración

1 objetos locales declaradas explícitamente automático o cuando se registra o no explícitamente declaradas estática o extern tiene una duración de almacenamiento automática. El almacenamiento para dura hasta que se crea el bloque en el que se crearon.

  • ¿Cuál es el efecto real de la instrucción de retorno

6.6.3 La instrucción de retorno

2 (...) el valor de la expresión es devuelto a la persona que llama de la función

y

6.6 declaraciones Jump (retorno pertenece a saltar declaraciones)

2 En la salida de un ámbito de aplicación (sin embargo lograrse), destructores (12.4) se llaman para todos los objetos construidos con una duración de almacenamiento automático (3.7.2)

  • ¿Qué garantiza que se produce el efecto

6.7 Declaración comunicado

2 variables con el tiempo de almacenamiento automático declarada en el bloque se destruyeron a la salida del bloque de

y

12.4 Los destructores se invocan

10 destructores implícitamente (1) para un objeto construido con duración de almacenamiento estático (3.7.1) en programa de terminación (3.6.3), (2) para un objeto construido con la duración de almacenamiento automático (3.7.2) cuando el bloque en el que se crea el objeto salidas (6.7)

No es fácil de comprender los detalles de una sola idea dispersos por todo el estándar de C++. Afortunadamente, una descripción general rápida también lo ayudará a hacer ese análisis.

7

Sí, se llamará a bar() antes del destructor de foo.

El estándar dice: 6.6: "a la salida de un ámbito de aplicación (sin embargo logra), destructores (12.4) son llamadas para todos los objetos construidos con una duración de almacenamiento automático (3.7.2) (objetos o temporales con nombre) que se declaran en ese alcance, en el orden inverso al de su declaración ".

El alcance no se deja hasta que se completa la declaración de devolución.

5

El resultado de la llamada a la barra() debe evaluarse antes de que el marco de pila que contiene Foo se pueda limpiar, así que sí, se llamará a bar() antes de Foo :: ~ Foo().

3

Objetos destruidos al salir del osciloscopio.

return sale del alcance, pero no puede regresar hasta que se haya ejecutado bar(). Se llama Ergo, bar().

2

Solo piense, ¿y si fuera return bar(foo);? Eso solo tiene para funcionar, y sería una tontería si el orden de destrucción fuera diferente dependiendo de si lo pasa como argumento o no.

Cuestiones relacionadas