2013-01-10 11 views
14

Ho appena saputo ieri che specificare parametri per gli elementi di elenco di inizializzazione è facoltativo. Tuttavia, quali sono le regole per ciò che accade in questo caso?Valori predefiniti in elenchi di inizializzatori C++

Nell'esempio seguente, ptr verrà inizializzato su 0, passerà a falso e Bar predefinito-costruito? Immagino che questa domanda sia ridondante, perché ci sarebbe poco da fare negli elenchi di inizializzatori se valori degli argomenti non specificati == comportamento non definito.

Potrei anche essere indirizzato alla sezione dello standard C++ che indica il comportamento nel caso degli elementi dell'elenco di inizializzazione non vengono forniti argomenti?

class Bar 
{ 
    Bar() { } 
}; 

class SomeClass; 
class AnotherClass 
{ 
public: 
    SomeClass *ptr; 
    bool toggle; 
    Bar bar; 

    AnotherClass() : ptr(), toggle(), bar() { } 
    // as opposed to... 
    // AnotherClass() : ptr(NULL), toggle(false), bar(Bar()) { } 
}; 
+0

Possibile duplicato di [Elenco di inizializzazione del costruttore con inizializzazione vuota] (https://stackoverflow.com/questions/11164394/constructor-initialization-list-with-empty-initialization) – Justin

risposta

12

Sì, i membri verranno inizializzati a zero e un oggetto predefinito costruito rispettivamente.

Il C++ 11 specifica standard di questo comportamento in 12.6.2/7:

L'espressione-elenco o rinforzato-init-elenco in un mem-inizializzatore viene utilizzato per inizializzare subobject designato (o, nel caso di un costruttore delegante , l'oggetto classe completo) in base alle regole di inizializzazione di 8.5 per l'inizializzazione diretta.

A sua volta, 8.5/10 legge:

Un oggetto le cui inizializzatore è un insieme vuoto di parentesi, cioè(), sarà valore-inizializzato.

Paragrafo 8.5/7 definisce valore-inizializzato:

Per valore-inizializzare un oggetto di tipo T significa:

  • se T è un gruppo (possibilmente cv-qualificato) tipo di classe (clausola 9) con un costruttore fornito dall'utente (12.1), quindi viene chiamato il costruttore predefinito per T (e l'inizializzazione non è corretta se T non ha un valore predefinito accessibileCostruttore);
  • se T è un gruppo (possibilmente cv-qualificata) non union tipo di classe senza un costruttore fornita dall'utente, l'oggetto è zero inizializzato e, se implicitamente dichiarata costruttore di default del T non è banale, che il costruttore viene chiamato.
  • se T è un tipo di matrice, allora ogni elemento è inizializzato a valore;
  • In caso contrario, l'oggetto è inizializzato a zero.

Infine, 8,5/5 definisce zero inizializzata:

a zero-inizializzare un oggetto o di riferimento di tipo T significa:

  • se T è un di tipo scalare (3.9), l'oggetto è impostato sul valore 0 (zero), assunto come un'espressione costante integrale, convertita in T;
  • se T è un gruppo (possibilmente cv-qualificata) non union tipo di classe , ogni dati non statici persona e ogni sotto-oggetto classe base è zero-inizializzato e imbottitura viene inizializzato a zero bit;
  • se T è un tipo unione (eventualmente qualificato per cv) , il primo membro dati non statico denominato dell'oggetto è zero- inizializzato e il riempimento è inizializzato su zero bit;
  • se T è un tipo di matrice , ogni elemento è inizializzato a zero;
  • se T è un tipo di riferimento , non viene eseguita alcuna inizializzazione.
+0

Eccellente e dettagliato. Proprio quello che stavo cercando - grazie! –

2

Inizializzazioni sono coperti in [dcl.init] (alias 8.5)

punto 10 afferma:

Un oggetto le cui inizializzatore è un insieme vuoto di parentesi, cioè,(), deve essere inizializzato a valore.

Value-inizializzazione è, messo semplicemente, la costruzione di default per le classi e zero inizializzazione per i tipi non-classe.

6

Nell'esempio riportato di seguito, sarà Ptr essere inizializzati a 0, alternare a false e bar default-costruiti?

Sì. Se un inizializzatore di membri viene visualizzato nell'elenco di inizializzazione con parentesi vuote, tale membro è il valore inizializzato. Ciò significa che i tipi numerici verranno inizializzati a zero, i puntatori a null e le classi con i costruttori predefiniti che utilizzano quel costruttore.

Se non si include affatto il membro nell'elenco di inizializzazione, sarà invece predefinito inizializzato; in quel caso. i tipi numerici e di puntatore verranno lasciati non inizializzati.

Potrei anche essere indirizzato alla sezione dello standard C++ che indica il comportamento nel caso degli elementi dell'elenco di inizializzazione non vengono forniti argomenti?

C++ 11 12.6.2/7 specifica che le regole sono le stesse dell'inizializzazione diretta.

C++ 11 8.5/16 specifica che se l'inizializzatore è (), l'oggetto viene inizializzato in base al valore.

C++ 11 8.5/7 definisce l'inizializzazione del valore.