Inizializzazione esplicita
Il linguaggio C++ supporta due forme di inizializzazione esplicita.
Fornendo un elenco di inizializzatori fra parentesi:
String sFileName( "FILE.DAT" );
Gli elementi nell'elenco tra parentesi vengono considerati argomenti nel costruttore di classe. Questa forma di inizializzazione consente l'inizializzazione di un oggetto con più valori e può essere utilizzata con l'operatore new. Di seguito è riportato un esempio.
Rect *pRect = new Rect( 10, 15, 24, 97 );
Fornendo un singolo inizializzatore utilizzando la sintassi di inizializzazione del segno di uguale. Di seguito è riportato un esempio.
String sFileName = "FILE.DAT";
Sebbene l'esempio precedente funzioni in modo analogo a quello dell'esempio illustrato per String nel primo elemento di elenco, la sintassi non può essere adattata per essere utilizzata con gli oggetti allocati sull'archivio libero.
La singola espressione a destra del segno di uguale viene utilizzata come argomento nel costruttore di copia della classe; pertanto, deve essere un tipo che può essere convertito nel tipo della classe.
Si noti che, poiché il segno di uguale (=) nel contesto di inizializzazione è diverso da un operatore di assegnazione, l'esecuzione dell'overload di operator= non ha effetto sull'inizializzazione.
La sintassi di inizializzazione del segno di uguale è diversa da quella di tipo funzione, anche se il codice generato è identico nella maggior parte dei casi. La differenza è data dal fatto che, quando la sintassi del segno di uguale verrà utilizzata, il compilatore deve comportarsi come se la seguente sequenza di eventi fosse in corso di esecuzione:
Creazione di un oggetto temporaneo dello stesso tipo dell'oggetto inizializzato.
Copia dell'oggetto temporaneo nell'oggetto.
Il costruttore deve essere accessibile prima che il compilatore possa eseguire questi passaggi. Anche se il compilatore può eliminare la creazione temporanea e copiare i passaggi nella maggior parte dei casi, un costruttore di copia non accessibile provoca la mancata l'inizializzazione del segno di uguale (in /Za, /Ze (Disabilita estensioni linguaggio)). Si consideri l'esempio seguente:
// spec1_explicit_initialization.cpp
// compile with: /Za
class anInt {
anInt( const anInt © ) {} // private copy constructor
public:
anInt( int ) {} // public constructor
};
int main() {
// Access-control violation.
// Attempt to reference private copy constructor.
anInt myInt = 7; // C2248
anInt myInt2(7); // Correct; no copy constructor called.
}
Quando una funzione viene chiamata, gli argomenti di tipo di classe passati per valore e gli oggetti restituiti per valore vengono inizializzati a livello concettuale utilizzando il formato:
type-name name = value
Di seguito è riportato un esempio.
String s = "C++";
Pertanto, ne consegue che il tipo di argomento deve essere un tipo che può essere convertito nel tipo della classe che viene passato come argomento. Il costruttore di copia della classe nonché gli operatori di conversione definiti dall'utente o i costruttori che accettano il tipo dell'argomento effettivo, devono essere pubblici.
Le espressioni che utilizzano l'operatore new, gli oggetti allocati sull'archivio libero vengono inizializzati a livello concettuale utilizzando il formato:
type-name name**(** initializer1, initializer2, ... initializern )
Di seguito è riportato un esempio.
String *ps = new String( "C++" );
Gli inizializzatori per i componenti della classe base e gli oggetti membri di una classe vengono inizializzati anche a livello concettuale in questo modo. Per ulteriori informazioni, vedere Inizializzazione di basi e membri.