2010-02-05 12 views

risposta

48

Da § 3.6.3 dello standard C++ 03:

I distruttori (12.4) per oggetti inizializzati di durata di memorizzazione statica (dichiarati nell'ambito di un blocco o nell'ambito di un namespace) sono chiamati come risultato del ritorno da main e come risultato dell'uscita di chiamata (18.3). Questi oggetti vengono distrutti nell'ordine inverso del completamento del loro costruttore o del completamento della loro inizializzazione dinamica. Se un oggetto viene inizializzato staticamente, l'oggetto viene distrutto nello stesso ordine come se l'oggetto fosse inizializzato dinamicamente. Per un oggetto di tipo array o classe, tutti i sottooggetti di quell'oggetto vengono distrutti prima che qualsiasi oggetto locale con durata di archiviazione statica inizializzata durante la costruzione degli oggetti secondari venga distrutto.

Inoltre, § 9.4.2 7 paese:

membri di dati statici vengono inizializzati e distrutti esattamente come oggetti non locali (3.6.2, 3.6.3).

Tuttavia, se un distruttore non ha alcun comportamento osservabile, non può essere invocato. Terry Mahaffey dettaglia questo nel suo answer to "Is a C++ destructor guaranteed not to be called until the end of the block?".

+1

Proprio come un'osservazione: Visual C++ 2010 sembra ignorare questo standard (tra gli altri). Non sono riuscito a prendere il punto di interruzione in un distruttore di test. Vedi: http://pastebin.com/sCMFYhzZ – progician

+1

@progician: il distruttore ha un comportamento osservabile? È possibile che VC++ '10 sia stato autorizzato ad escludere la chiamata del distruttore. Prova a stampare un prompt, quindi a leggere l'input o ad aprire un file e scriverci sopra nel distruttore. – outis

+0

... Naturalmente, non sarei troppo sorpreso se VC++ ignorasse lo standard. – outis

3

da qualche parte dopo "principale"

(non si può sapere o fare affidamento su l'ordine esatto in cui essi sono chiamati)

+5

Succede che _before_ 'std :: cout' è distrutto. Cioè puoi stampare cose lì. – MSalters

+0

@MSalters Suppongo che sia solo un dettaglio della tua particolare implementazione e/o l'ordine in cui hai dichiarato i tuoi oggetti relativi a 'cout' o alla prima chiamata che richiama il suo costruttore (ad esempio' operator <<() '). Dubito che sia garantito, nel qual caso, vorrei sottolineare il "non posso fare affidamento su" in questa risposta. –

+1

@underscore_d: No, è sicuramente una garanzia. È possibile perché la libreria standard è speciale/conosciuta per l'implementazione. – MSalters

Problemi correlati