2012-04-18 9 views
60

In C++, se un costruttore genera un'eccezione, ciò che i distruttori è gestita?Quali distruttori vengono eseguiti quando il costruttore genera un'eccezione?

In particolare, Fa qualche differenza se l'eccezione è durante l'elenco di inizializzazione o il corpo?

Inoltre, per quanto riguarda l'ereditarietà e soci? Presumibilmente tutte le costruzioni completate vengono distrutte. Se solo alcuni membri sono costruiti, solo quelli vengono distrutti? Se esiste un'ereditarietà multipla, tutti i costruttori completati vengono distrutti? L'ereditarietà virtuale cambia qualcosa?

+2

C'è qualche ragione per cui non l'hai testato tu stesso? –

+23

@Steve: Perché basarsi sul comportamento di una particolare versione del compilatore è una pessima idea se si desidera un codice portatile o gestibile. –

+0

@ BenVoigt - Sono d'accordo in teoria. Ma quando stai codificando nel mondo reale, devi affrontare la realtà. E sarei estremamente sorpreso se tutti i principali compilatori non avessero ragione. –

risposta

57

se un costruttore genera un'eccezione, quali distruttori vengono eseguiti?

I distruttori di tutti gli oggetti creati completamente in tale ambito.

Fa alcuna differenza se l'eccezione è durante l'elenco di inizializzazione o il corpo?

Tutti gli oggetti completati verranno distrutti.
Se costruttore è mai completamente chiamato oggetto non è mai stato costruito e pertanto non può essere distrutto.

E l'eredità ei membri? Presumibilmente tutte le costruzioni completate vengono distrutte. Se solo alcuni membri sono costruiti, solo quelli vengono distrutti? Se esiste un'ereditarietà multipla, tutti i costruttori completati vengono distrutti? L'ereditarietà virtuale cambia qualcosa?

Tutte le costruzioni completate vengono distrutte. Sì, solo gli oggetti completamente creati vengono distrutti.

Buona Lettura:

Constructor Failures by Herb Sutter

In particolare, l'amore la parte in cui si spiega:

In termini biologici, il concepimento è avvenuto - il costruttore ha iniziato -, ma nonostante i migliori sforzi è stato seguito da un aborto spontaneo - il costruttore non ha mai corso a termine (inazione).

Per inciso, questo è il motivo per cui un distruttore non verrà mai chiamato se il costruttore non ha avuto successo - non c'è nulla da distruggere. "Non può morire, perché non è mai vissuto." Si noti che questo rende la frase "un oggetto il cui costruttore ha generato un'eccezione" davvero un ossimoro. Una cosa del genere è ancora meno di un ex oggetto ... non è mai vissuto, mai è stato, non ha mai respirato per primo.

+0

Cosa diavolo è un "ambito logico"? –

+1

Si potrebbe anche voler leggere la [risposta precedente] di Als (http://stackoverflow.com/a/9972063/179910) su più o meno lo stesso argomento. –

4

Qualsiasi oggetto creato in un ambito locale lasciato a causa del costruttore sarà essere distrutto. La gestione runtime torna indietro lo stack, chiamando distruttori, finché non trova un gestore.

Se l'eccezione viene generata da un costruttore, verranno chiamati i distruttori di tutti gli oggetti secondari completamente creati. Inoltre, se il costruttore faceva parte di un'espressione new, verrà richiamato l'operatore di posizionamento appropriato se esistente.

+0

+1 per la descrizione di cosa succede con le espressioni new'd. Questo è importante. –

14

In C++, se un costruttore genera un'eccezione, quali distruttori vengono eseguiti?

Tutti gli oggetti che hanno avuto costruttori corrono fino al completamento.

In particolare, Fa qualche differenza se l'eccezione è durante l'elenco di inizializzazione o il corpo?

No. Tutti i membri completamente costruiti prima dell'eccezione eseguiranno i propri distruttori. Il membro che ha gettato durante la costruzione e tutti gli altri membri non costruiti saranno non con i loro distruttori in esecuzione. L'ordine di costruzione dei membri è ben definito e quindi sai esattamente cosa accadrà dato che conosci il punto dell'eccezione.

Inoltre, che ne è dell'ereditarietà e dei membri?

Si applica la stessa regola.

Presumibilmente tutte le costruzioni completate vengono distrutte.

Se solo alcuni membri sono costruiti, fanno solo quelli get destructed?

Se c'è ereditarietà multipla, fanno tutti i costruttori completati ottenere destructed?

Vuol eredità virtuale cambia nulla?

No.
Ma nota: l'eredità virtuale influisce l'ordine i costruttori sono chiamati. Se non si conosce come viene definito l'ordine, ciò potrebbe non essere intuitivo fino a quando non si osservano le regole esatte.

Problemi correlati