Partager via


Initialisation explicite

C++ prend en charge deux formes d'initialisation explicite.

  • Fournir une liste d'initialiseurs entre parenthèses :

    String sFileName( "FILE.DAT" );
    

    Les éléments de la liste entre parenthèses sont considérés comme des arguments du constructeur de classe. Cette forme d'initialisation active l'initialisation d'un objet avec plusieurs valeurs et peut également être utilisée conjointement avec l'opérateur new. Par exemple :

    Rect *pRect = new Rect( 10, 15, 24, 97 );
    
  • Fournir un initialiseur unique à la syntaxe d'initialisation avec signe égal. Par exemple :

    String sFileName = "FILE.DAT";
    

    Bien que l'exemple précédent fonctionne de la même manière que l'exemple indiqué pour String dans le premier élément de la liste, cette syntaxe ne peut pas être utilisée avec des objets alloués dans le magasin libre.

    L'expression unique à droite du signe égal est considérée comme argument du constructeur de copie de la classe ; par conséquent, ce doit être un type qui peut être converti en type de classe.

    Notez qu'étant donné que le signe égal (=) dans le contexte de l'initialisation est différent d'un opérateur d'assignation, le fait de surcharger operator= n'a aucun effet sur l'initialisation.

La syntaxe d'initialisation avec signe égal est différente de la syntaxe de style fonction, même si le code généré est identique dans la plupart des cas. La différence réside dans le fait que lorsque la syntaxe avec signe égal est utilisée, le compilateur doit se comporter comme si la séquence d'événements suivante se produisait :

  • Création d'un objet temporaire du même type que l'objet initialisé.

  • Copie de l'objet temporaire vers l'objet.

Le constructeur doit être accessible avant que le compilateur puisse exécuter ces étapes. Bien que le compilateur puisse éliminer la création temporaire et copier des étapes dans la plupart des cas, un constructeur de copie inaccessible entraîne l'échec de l'initialisation avec signe égal (sous /Za, /Ze (Désactivation des extensions de langage)). Prenons l'exemple suivant :

// spec1_explicit_initialization.cpp
// compile with: /Za
class anInt {
   anInt( const anInt &copy ) {}   // 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.
}

Lorsqu'une fonction est appelée, les arguments de type classe sont transmis par valeur et les objets retournés par valeur sont initialisés conceptuellement sous la forme suivante :

type-name name = value

Par exemple :

String s = "C++";

Par conséquent, le type d'argument doit être un type pouvant être converti en type de classe transmis comme argument. Le constructeur de copie de la classe, ainsi que les opérateurs ou les constructeurs de conversion définis par l'utilisateur qui acceptent le type de l'argument réel, doivent être publics.

Dans les expressions qui utilisent l'opérateur new, les objets alloués dans le magasin libre sont initialisés conceptuellement sous la forme suivante :

type-name name**(** initializer1, initializer2, ... initializer)

Par exemple :

String *ps = new String( "C++" );

Les initialiseurs pour les composants de classe de base et des objets membres d'une classe sont également initialisés conceptuellement de cette façon. (Pour plus d'informations, consultez Initialisation des bases et des membres.)

Voir aussi

Référence

Initialisation avec les fonctions membres spéciales