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.