2012-04-11 18 views
11

Mi sono imbattuto in qualche problema di eccezione che non mi è chiaro. In C++, quando un oggetto viene lanciato, viene dapprima copiato su un oggetto temporaneo e l'oggetto temporaneo viene quindi passato al codice catching. La copia implica l'uso del costruttore di copia di classe dell'oggetto. AFAIK, questo significa che se una classe ha un costruttore di copie privato, non può essere utilizzata come eccezione. Tuttavia, in VS2010, il seguente codice viene compilato ed eseguito:Possono essere lanciati oggetti con costruttori di copia privati?

class Except 
{ 
    Except(const Except& other) { i = 2; } 
public: 
    int i; 
    Except() : i(1) {} 
}; 

int main() 
{ 
    try 
    { 
     Except ex1; 
     throw ex1;   // private copy constructor is invoked 
    } 
    catch (Except& ex2) 
    { 
     assert(ex2.i == 2); // assert doesn't yell - ex2.i is indeed 2 
    } 
    return 0; 
} 

È legale?

+0

Prova ad aggiungere stampe o debug e vedi l'ordine delle chiamate, forse le cose non vengono eseguite esattamente come pensi che facciano. – selalerer

+1

Ho lo stesso comportamento con VS2010 ma non riesce [qui] (http://ideone.com/RlOjl) con gcc v4.3.4. – hmjd

+0

Potrebbe essere che l'oggetto temporaneo è ciò che viene costruito e la copia viene ottimizzata. Simile all'ottimizzazione del valore di ritorno. –

risposta

13

Non è legale. Standard di 15,1/5

Se l'utilizzo dell'oggetto temporaneo può essere eliminato senza cambiare il significato del programma, tranne per l'esecuzione dei costruttori e distruttori associati con l'uso dell'oggetto temporaneo (12.2), quindi l'eccezione nel gestore può essere inizializzata direttamente con l'argomento dell'espressione di lancio. Quando l'oggetto generato è un oggetto di classe e il costruttore di copie utilizzato per inizializzare la copia temporanea non è accessibile, il programma è in formato non valido (anche se l'oggetto temporaneo potrebbe essere altrimenti eliminato). Allo stesso modo, se il distruttore per quell'oggetto non è accessibile, il programma è non formattato (anche se l'oggetto temporaneo potrebbe altrimenti essere eliminato).

+0

Wow è incredibile, non avrei mai immaginato che potesse accadere. grazie. – petric

2

No, non lo è.

15.1.5 Quando l'oggetto lanciato è un oggetto di classe, il costruttore di copia/spostamento e il distruttore deve essere accessibile, anche se l'operazione di copia/spostamento viene eliso

Problemi correlati