2012-01-18 4 views
8

Ultimamente, ho letto molto sui costruttori dal ben ricevuto C++ FAQ. Una delle voci menziona che è sempre meglio usare gli elenchi di inizializzazione, invece di inizializzare i membri della classe all'interno del blocco di codice del costruttore stesso.Inizializzazione dei membri della classe Non-pointer

Questo perché il compilatore tende a creare più copie dei membri della classe, piuttosto che una sola copia.

Esempio

Buono

Foo::Foo(void) 
    : mBar(new Bar) //pointer to some memory address 
{ 
} 

Bad

Foo::Foo(void) 
{ 
    mBar = new Bar; 
} 

Una cosa si afferma anche (e, mentre questo si riferisce a costruttori, si riferisce anche al puro inizializzazione di oggetti in generi l dalle funzioni anche terzi) è che quando l'inizializzazione di un oggetto attraverso metodi come la seguente:

void f(void) 
{ 
    Foo foo(Bar()); //Bad. 

    foo.x(); //error 
} 

Si vuole, e cito: "[declare] a non-member function that returns a Foo object".

(per maggiori informazioni clicca sul link qui sopra)

La questione

A causa di questo, è saggio avere il seguente:

O anche questo:

Geometry::Geometry(void) 
    : mFaces(QVector<GLushort>), 
     mFinalized(false), 
     mNormals(QVector<QVector3D>), 
     mVerticies(QVector<QVector3D>) 

A causa del modo in cui t Questi sono assegnati (cioè, il fatto che questi siano non puntatori), mi chiedo se questi oggetti abbiano o meno bisogno di inizializzarli all'inizio. Se lo fanno, è questo il metodo corretto per farlo? O c'è un metodo migliore di inizializzazione?

come questo si riferisce alla domanda

Ciò si riferisce alla questione generale a causa del modo in cui la metodologia alla base C++ inizializzazione del costruttore si riferisce a entrambi gli oggetti di inizializzazione utilizzando funzioni di costruzione, insieme al fatto che io sono ignorante a prescindere dal fatto che gli oggetti siano allocati nello stack o, in ogni caso, credo - (in entrambi i casi, gli oggetti senza allocazione del puntatore) anche necessitano di inizializzazione in primo luogo.

risposta

12

Se una variabile membro è di un tipo di classe con un costruttore predefinito dichiarato dall'utente, non è necessario specificarlo esplicitamente nell'elenco di inizializzazione: il suo costruttore predefinito verrà chiamato comunque, durante la costruzione, prima del corpo del costruttore è inserito.

Se una variabile membro è un tipo primitivo (come int o bool) oppure è di un tipo di classe che non ha alcun costruttore dall'utente dichiarato, è necessario inizializzare esplicitamente, altrimenti non verrà inizializzata (e avrà un valore sconosciuto, non puoi leggere un oggetto non inizializzato).

+0

Quindi, questo significa che, in base al codice sopra, sto solo creando più copie degli oggetti che sto allocando? – zeboidlund

+3

Quando si utilizza 'mFaces (QVector < GLushort >())', si costruisce un 'QVector ' temporaneo, copia il costrutto 'mFaces' da quell'oggetto temporaneo, quindi distrugge quell'oggetto temporaneo. Quindi, sì, stai creando più oggetti del necessario. –