Il default member initializer è una costruzione di C++11 che consente di dichiarare valori predefiniti direttamente durante la dichiarazione delle variabili membre della classe. Questa possibilità è spesso confusa con altri modi di inizializzare i dati.
Le versioni precedenti di C++ non permettevano di inizializzare i membri direttamente durante la dichiarazione; i valori venivano assegnati solo nel costruttore (nel corpo o nella lista di inizializzazione). L'introduzione dei default member initializers (C++11) ha migliorato la leggibilità e ridotto il rischio di errori di inizializzazione indefinita.
Se i campi non sono inizializzati esplicitamente, contengono un valore "spazzatura" (indefinito). L'assegnazione all'interno del costruttore è meno efficiente rispetto alla lista di inizializzazione, e ignorare i default member initializers complica l'estensione delle classi e la creazione di nuovi costruttori.
Utilizzare i default member initializers per i valori semplici, e per casi complessi (soprattutto se è necessario un valore dipendente o non standard) — le liste di inizializzazione del costruttore.
Esempio di codice:
class Widget { int x = 42; // default member initializer std::string name = "default"; // default member initializer public: Widget() = default; // x=42, name="default" Widget(int xx) : x(xx), name("new") {}// x=xx, name="new" };
Caratteristiche principali:
Si applica il default member initializer se un membro è inizializzato nel corpo del costruttore, ma non nella lista di inizializzazione?
Risposta:
No. Se non specificato nella lista di inizializzazione, la variabile verrà prima inizializzata con il valore predefinito (default member initializer), e poi nel corpo del costruttore ci sarà un'assegnazione, che è meno efficiente.
Qual è l'ordine di inizializzazione dei membri della classe con default member initializers nell'ereditarietà?
Risposta:
Prima vengono inizializzati i membri della classe base, poi quelli della classe derivata; per ogni membro con default member initializer viene utilizzata prima la lista di inizializzazione del costruttore, se presente, poi il default member initializer, altrimenti rimane non inizializzato (per POD). Non avviene "doppia inizializzazione".
Può il default member initializer essere applicato ai membri statici della classe?
Risposta:
No, i membri statici non possono essere inizializzati tramite default member initializer. Devono essere inizializzati al di fuori della classe o tramite inline static in C++17.
Esempio:
struct S { static int a = 5; // Errore! };
Classe con una stringa dinamica, che è stata dimenticata durante l'inizializzazione in alcuni costruttori. Successivamente, durante l'accesso — comportamento indefinito.
Vantaggi:
Svantaggi:
Tutti i campi hanno default member initializers. I costruttori aggiuntivi, se necessario, inizializzano esplicitamente i membri necessari tramite la lista di inizializzazione.
Vantaggi:
Svantaggi: