2015-01-04 13 views
20

Voglio evitare che l'utente della mia classe di utilizzarlo come una variabile automatica, quindi mi scrivere codice come questo:Qual è la differenza tra il distruttore "= default" e il distruttore vuoto?

class A { 
private: 
    ~A() = default; 
}; 

int main() { 
    A a; 
} 

mi aspetto che il codice non sarà compilato, ma g ++ compila senza errori .

Tuttavia, quando cambio il codice per:

class A { 
private: 
    ~A(){} 
}; 

int main() { 
    A a; 
} 

Ora, g ++ dà l'errore che ~A() è privato, come è la mia aspettativa.

Qual è la differenza tra un distruttore "= predefinito" e un distruttore vuoto?

+4

Quale versione di gcc? –

+1

Lettura ad es. [questo riferimento del distruttore] (http://en.cppreference.com/w/cpp/language/destructor), la differenza è che un distruttore fornito dall'utente (anche se è vuoto) è * non banale *, e dal reference: "Gli oggetti con distruttori banali non richiedono un'espressione delete e possono essere eliminati semplicemente trasferendo la loro memoria." –

+8

Nel tuo caso non c'è differenza, sia [gcc4.9 che clang3.5 rifiutano di compilare] (http://coliru.stacked-crooked.com/a/41976bc03bc12c79) il tuo primo esempio. Deve essere un bug nella tua versione di gcc. – Praetorian

risposta

23

Il tuo primo esempio non dovrebbe essere compilato. Questo rappresenta un bug nel compilatore che viene compilato. Questo bug è stato risolto in gcc 4.9 e versioni successive.

Il distruttore definito con = default è banale in questo caso. Questo può essere rilevato con std::is_trivially_destructible<A>::value.

Aggiornamento

C++ 11 (e C++ 14) affermano che se uno ha un'user-dichiarata distruttore (e se non si dispone di uno user-dichiarato sposta membro speciale) , quindi la generazione implicita del costruttore di copie e dell'operatore di assegnazione delle copie avviene ancora, ma tale comportamento è deprecato. Significato se ci si basa su di esso, il compilatore potrebbe darvi un avvertimento di deprecazione (o potrebbe non).

Entrambi:

~A() = default; 

e:

~A() {}; 

sono dall'utente dichiarato, e quindi hanno alcuna differenza rispetto a questo punto. Se si utilizza uno di questi moduli (e non si dichiarano membri di spostamento), è necessario impostare in modo esplicito, eliminare esplicitamente o fornire esplicitamente i membri di copia per evitare di fare affidamento sul comportamento deprecato.

Se si dichiarano membri di spostamento (con o senza dichiarazione di un distruttore), i membri di copia vengono eliminati implicitamente.

+2

@delphifirst: I bug del compilatore sono molto comuni in questi giorni. Quando ero uno studente, nei primi anni '80, abbiamo appreso che sicuramente qualsiasi comportamento non corretto era un bug nel nostro codice, non nel compilatore. Oggi faccio regolarmente crash dei compilatori (ICE, Internal Compiler Error), e quindi non c'è alcun dubbio su di chi sia la colpa ... –

+0

@HowardHinnant: mi manca un po 'di discussione sul default rispetto a non dichiarato. Penso che si riferirebbe all'uso standard della frase "utente dichiarato", ad es. in C++ 11 §12.8/18. Per favore? –

+0

@ Cheersandhth.-Alf: Felice di aiutare, ma non capisco la tua domanda. Se stai chiedendo se un membro speciale '= defaulted' è dichiarato dall'utente, la risposta è sì, ma non fornita dall'utente. –

Problemi correlati