441 votes

Quelle est cette syntaxe bizarre du côlon-membre dans le constructeur ?

Récemment, j’ai vu un exemple comme suit :

En quoi consiste cet étrange veux dire ? Il semble en quelque sorte pour initialiser la variable membre mais je n’ai jamais vu cette syntaxe avant. Il ressemble à un appel de fonction/constructeur, mais pour un ? N’a aucun sens pour moi. Peut-être quelqu'un pourrait m’éclairer. Et, par ailleurs, y a-t-il d’autres fonctionnalités de langage ésotérique comme ça, vous ne trouverez jamais dans un livre de C++ ordinaire ?

418voto

Alok Save Points 115848
Foo(int num): bar(num)    

Ce concept est appelé un Membre de la Liste d'Initialiseur en C++.

Simplement dit, il initialise votre membre bar valeur num.


Quelle est la différence entre l'Initialisation et Affectation à l'intérieur d'un constructeur?

L'Initialisation De Membre:

Foo(int num): bar(num) {};

Membre De La Mission:

Foo(int num)
{
   bar = num;
}

Il existe une différence significative entre l'Initialisation d'un membre à l'aide de initialiseur de Membre de la liste et de lui affecter une valeur à l'intérieur du corps du constructeur.

Lorsque vous initialisez des champs via initialiseur de Membre de la liste des constructeurs sera appelé une fois et l'objet sera construit et initialisé en une seule opération.

Si vous utilisez d'attribution de ces champs sera d'abord initialisé avec les constructeurs par défaut et puis réaffectés (via l'opérateur d'affectation) avec des valeurs réelles.

Comme vous le voyez il y a une surcharge supplémentaire de création et d'affectation dans le second, ce qui pourrait être considérable pour l'utilisateur défini par les classes.

Cost of Member Initialization = Object Construction 
Cost of Member Assignment = Object Construction + Assignment

Ce dernier est en fait équivalent à:

Foo(int num) : bar() {bar = num;}

Alors que le premier est l'équivalent d'un peu:

Foo(int num): bar(num){}

Pour une fonction intégrée de (votre exemple de code) ou POD membres de la classe il n'est pas pratique de surcharge.


Quand devez-vous utiliser Initialiseur de Membre de la liste?

Vous avez(un peu forcé) à utiliser un Initialiseur de Membre de la liste si:

  • Votre classe a un membre de référence
  • Votre classe a non static const membre ou
  • Votre membre de la classe ne possède pas de constructeur par défaut ou
  • Pour l'initialisation de la base de membres de la classe ou
  • Lors du constructeur nom du paramètre est le même que le membre de données(ce n'est pas vraiment un must)

Un exemple de code:

class MyClass
{
    public:
        //Reference member, has to be Initialized in Member Initializer List
        int &i;       
        int b;
        //Non static const member, must be Initialized in Member Initializer List
        const int k;  

    //Constructor's parameter name b is same as class data member 
    //Other way is to use this->b to refer to data member
    MyClass(int a, int b, int c):i(a),b(b),k(c)
    {
         //Without Member Initializer
         //this->b = b;
    }
};

class MyClass2:public MyClass
{
    public:
        int p;
        int q;
        MyClass2(int x,int y,int z,int l,int m):MyClass(x,y,z),p(l),q(m)
        {
        }

};

int main()
{
    int x = 10;
    int y = 20;
    int z = 30;
    MyClass obj(x,y,z);

    int l = 40;
    int m = 50;
    MyClass2 obj2(x,y,z,l,m);

    return 0;
}
  • MyClass2 n'ont pas de constructeur par défaut de sorte qu'il doit être initialisé par le biais de membre de la liste d'initialiseur.
  • Classe de Base MyClass n'ont pas de constructeur par défaut, Afin d'initialiser son membre, il faudra utiliser Initialiseur de Membre de la Liste.

Version en ligne de l'exemple de code.


Points importants à Noter lors de l'utilisation de Membre de l'Initialiseur de Listes:

Membre de la classe des variables sont toujours initialisés dans l'ordre dans lequel elles sont déclarées dans la classe.

Ils sont pas initialisés dans l'ordre dans lequel ils sont indiqués dans les États Initalizer Liste.
En bref, la liste d'initialisation de Membre ne permet pas de déterminer l'ordre de l'initialisation.

Compte tenu de ce qui précède, il est toujours une bonne pratique de conserver le même ordre des membres de l'initialisation de Membre que l'ordre dans lequel elles sont déclarées dans la définition de la classe. C'est parce que les compilateurs ne pas avertir si les deux commandes sont différentes mais relativement nouvelle, l'utilisateur peut confondre membre de la liste d'Initialiseur comme l'ordre de l'initialisation et écrire du code qui en dépendent.

249voto

James McNellis Points 193607

C'est un membre de la liste d'initialisation. Vous devriez trouver des informations à ce sujet dans tout bon C++ livre.

Vous devez, dans la plupart des cas, l'initialisation de tous les états des objets dans la liste d'initialisation de membre (cependant, notent les exceptions énumérées à la fin de l'article de la FAQ).

La vente à emporter-point à partir de l'entrée de la FAQ, c'est que,

Toutes autres choses étant égales par ailleurs, votre code sera exécuté plus rapidement si vous utilisez l'initialisation des listes plutôt que de l'affectation.

18voto

Josh Points 1346

C’est l’initialisation de constructeur. C’est la façon correcte pour initialiser les membres dans un constructeur de classe, car elle empêche le constructeur par défaut appelé.

Considérez ces deux exemples :

Dans l’exemple 1 :

Dans l’exemple 2 :

C’est tout au sujet de l’efficacité.

16voto

C’est ce qu’on appelle une liste d’initialisation. C’est une autre façon de l’initialisation de membres de la classe. Il existe des avantages à utiliser cela au lieu de simplement initialiser les membres dans le corps du constructeur, mais si vous initialisez les membres de classe qui sont des constantes ou des références qu’ils doivent être initialisées par l’intermédiaire de l’initialisation liste.

9voto

birryree Points 29165

Ce n’est pas obscur, c’est la syntaxe de liste d’initialisation C++

Fondamentalement, dans votre cas, sera initialisé avec , avec , avec .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X