2010-02-03 14 views
12

Supponiamo che io ho il seguente snipplet:C++ distruttore e chiamata di funzione fine

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

Ora, fa lo standard C++ mi garantisce che bar() sarà chiamato prima foo :: ~ Foo()? O è questa la scelta del compilatore/dell'implementazione?

Grazie!

+0

Che cosa ha da dire il tuo libro di testo C++ sull'argomento? –

+2

Di che libro parla questo? È come lo stack overflow, ma modificato e messo su carta? – anon

risposta

15

È un comportamento garantito. L'esecuzione effettiva viene srotolato come segue:

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() 

Ecco alcuni riferimenti dalla norma:

  • quale programma garanzie di esecuzione, in genere

1,9 L'esecuzione del programma

10 Un'istanza di ciascun oggetto con durata di archiviazione automatica (3.7.2) è associato a ciascuna voce nel blocco .

  • Il foo è di durata di stoccaggio automatico e:

3.7.2 memorizzazione automatica durata

1 oggetti locali dichiarate esplicitamente auto o la registrazione o non esplicitamente dichiarati statico o extern hanno durata di archiviazione automatica. L'archiviazione per dura fino a quando non viene chiuso il blocco in cui sono stati creati.

  • Qual è l'effetto reale del return

6.6.3 L'istruzione return

2 (...) il valore dell'espressione viene restituito al chiamante di la funzione

e

6.6 istruzioni di salto (ritorno appartiene a saltare dichiarazioni)

2 All'uscita da una portata (comunque realizzato), distruttori (12.4) sono chiamati per tutti oggetti costruiti con durata memorizzazione automatica (3.7.2)

  • Cosa garantisce che si verifica l'effetto

6.7 Dichiarazione dichiarazione

2 variabili con durata memorizzazione automatica dichiarato nel blocco vengono distrutte all'uscita dal blocco

e

12.4 distruttori vengono invocati

10 distruttori implicitamente (1) per un oggetto costruito con durata di memorizzazione statica (3.7.1) in Terminazione di programma (3.6.3), (2) per un oggetto costruito con durata memorizzazione automatica (3.7.2) quando il blocco in cui l'oggetto viene creato uscite (6,7)

Non è facile da afferrare i dettagli di una singola idea sparsi per tutto lo standard C++. Si spera che una rapida panoramica ti aiuti a fare anche tu questa analisi.

7

Sì, la barra() verrà chiamata prima del distruttore di foo.

Lo standard dice: 6.6: "Su uscita da un ambito (comunque realizzato), distruttori (12,4) sono chiamati per tutti gli oggetti costruiti con durata memorizzazione automatica (3.7.2) (oggetti o temporanei denominati) che sono dichiarati in tale ambito, nell'ordine inverso della loro dichiarazione. "

L'ambito non viene lasciato fino a quando non viene completata la dichiarazione di ritorno.

5

Il risultato della barra chiamante() deve essere valutato prima che il frame dello stack contenente Foo possa essere pulito, quindi yes, bar() verrà chiamato prima di Foo :: ~ Foo().

3

Gli oggetti si distruggono quando escono dall'ambito.

return lascia l'ambito, ma non può tornare finché non ha eseguito bar(). Ergo, bar() viene chiamato.

2

Basti pensare, e se fosse return bar(foo);? Questo solo ha il per funzionare, e sarebbe sciocco se l'ordine di distruzione fosse diverso a seconda che tu lo passassi come argomento o meno.

Problemi correlati