Que fait l'opérateur du côlon (":") dans ce constructeur? Est-ce équivalent à MyClass(m_classID = -1, m_userdata = 0);
?
class MyClass {
public:
MyClass() : m_classID(-1), m_userdata(0) {
}
int m_classID;
void *m_userdata;
};
Que fait l'opérateur du côlon (":") dans ce constructeur? Est-ce équivalent à MyClass(m_classID = -1, m_userdata = 0);
?
class MyClass {
public:
MyClass() : m_classID(-1), m_userdata(0) {
}
int m_classID;
void *m_userdata;
};
C'est une liste d'initialisation, et fait partie de l'constructeur de mise en œuvre.
Le constructeur de la signature est:
MyClass();
Ce qui signifie bien sûr que c'est un constructeur sans paramètre - là, de celui qui sera appelé par défaut lorsque vous écrivez MyClass someObject;
.
La part : m_classID(-1), m_userdata(0)
est appelée liste d'initialisation. C'est un moyen d'initialiser certains champs de votre objet (tous, si vous voulez) avec les valeurs de votre choix, au lieu de les laisser comme indéfini.
Après l'exécution de la liste d'initialisation, le corps du constructeur (qui s'avère être vide dans votre exemple) est exécutée. À l'intérieur de ce que vous pourriez faire plus de devoirs, mais une fois que vous l'avez saisi tous les champs ont déjà été initialisé - soit aléatoire, non spécifié des valeurs, ou de ceux que vous avez choisi dans votre liste d'initialisation. Cela signifie que les attributions faites dans le corps du constructeur ne sera pas initialisations, mais les changements de valeurs.
C'est une liste d'initialisation.
Par le temps que vous obtenez dans le corps du constructeur, tous les champs ont déjà été construits; s'ils ont des constructeurs par défaut, ceux qui ont été déjà appelé. Maintenant, si vous affectez une valeur à eux dans le corps du constructeur, vous appelez le constructeur de copie. Qui est inefficace, parce que les deux constructeurs finissent par être appelé au lieu d'un.
Ainsi, dans le cas de types primitifs comme int, il n'y a aucun avantage par rapport à l'affectation dans le corps du constructeur. Dans le cas des objets qui ont un constructeur, c'est une optimisation des performances, car elle évite d'appeler la fois le défaut et le constructeur de copie.
Une liste d'initialisation est nécessaire si l'un des champs est une référence, car une référence ne peut jamais être nul, pas même dans le court laps de temps entre la construction de l'objet et le corps du constructeur. Le suivant génère l'erreur C2758: "MyClass::member_' : doit être initialisé dans le constructeur de base/membre de la liste d'initialiseur
class MyClass {
public :
MyClass(std::string& arg) {
member_ = arg;
}
std::string& member_;
};
La seule façon correcte est:
class MyClass {
public :
MyClass(std::string& arg)
: member_(arg)
{
}
std::string& member_;
};
Voir le C++ FAQ pour une meilleure discussion.
Il indique le début d'une initialiser la liste, qui est pour l'initialisation des variables de membre de votre objet.
Pour: - MyClass(m_classID = -1, m_userdata = 0);
Qui déclare un constructeur qui peut prendre des arguments (si je pouvais créer un MyClass
l'aide MyClass m = MyClass(3, 4)
, ce qui entraînerait m_classID
3 et m_userdata
soit 4). Si je devais passer pas des arguments au MyClass
constructeur, il en résulterait un équivalent de l'objet en cours de création de la version avec l'initialiser la liste.
C'est une liste d'initialisation . Dans votre exemple, c'est plutôt quelque chose comme ceci (quelque chose comme ceci - ça ne veut pas dire que c'est équivalent dans tous les cas):
class MyClass {
public:
MyClass(){
m_classID = -1;
m_userdata = 0;
}
int m_classID;
void *m_userdata;
};
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.