En interne et à propos du code généré, y a-t-il vraiment une différence entre:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
et
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Merci...
En interne et à propos du code généré, y a-t-il vraiment une différence entre:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
et
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Merci...
En supposant que ces valeurs sont des types primitifs, alors non, il n'y a pas de différence. Les listes d'initialisation ne font une différence que lorsque vous avez des objets en tant que membres, car au lieu d'utiliser l'initialisation par défaut suivie d'une affectation, la liste d'initialisation vous permet d'initialiser l'objet à sa valeur finale. Cela peut en fait être sensiblement plus rapide.
Vous devez utiliser la liste d'initialisation pour initialiser les membres constants, les références et la classe de base
Lorsque vous devez initialiser un membre constant, des références et passer des paramètres aux constructeurs de classe de base, comme mentionné dans les commentaires, vous devez utiliser la liste d'initialisation.
L'exemple (non exhaustif) class / struct contient une référence:
Et exemple d'initialisation de la classe de base qui nécessite un paramètre (par exemple pas de constructeur par défaut):
la source
_capacity
,_data
et_len
avoir des types de classe sans constructeurs par défaut accessibles?const
membre dans le corps du constructeur, vous devez utiliser la liste d'initialisation - les nonconst
membres peuvent être initialisés dans la liste d'initialisation ou dans le corps du constructeur.Oui. Dans le premier cas, vous pouvez déclarer
_capacity
,_data
et_len
comme constantes:Cela serait important si vous souhaitez vous assurer de la
const
validité de ces variables d'instance lors du calcul de leurs valeurs au moment de l'exécution, par exemple:const
les instances doivent être initialisées dans la liste d'initialisation ou les types sous-jacents doivent fournir des constructeurs publics sans paramètre (ce que font les types primitifs).la source
Je pense que ce lien http://www.cplusplus.com/forum/articles/17820/ donne une excellente explication - en particulier pour ceux qui découvrent le C ++.
La raison pour laquelle les listes d'initialisation sont plus efficaces est que dans le corps du constructeur, seules les affectations ont lieu, pas l'initialisation. Donc, si vous avez affaire à un type non intégré, le constructeur par défaut de cet objet a déjà été appelé avant que le corps du constructeur n'ait été entré. Dans le corps du constructeur, vous attribuez une valeur à cet objet.
En fait, il s'agit d'un appel au constructeur par défaut suivi d'un appel à l'opérateur d'affectation de copie. La liste d'initialisation vous permet d'appeler directement le constructeur de copie, et cela peut parfois être beaucoup plus rapide (rappelez-vous que la liste d'initialisation est avant le corps du constructeur)
la source
J'ajouterai que si vous avez des membres de type classe sans constructeur par défaut disponible, l'initialisation est le seul moyen de construire votre classe.
la source
Une grande différence est que l'affectation peut initialiser les membres d'une classe parent; l'initialiseur ne fonctionne que sur les membres déclarés dans la portée de classe actuelle.
la source
Dépend des types impliqués. La différence est similaire entre
et
où la deuxième forme est une liste d'initialisation, c'est-à-dire que cela fait une différence si le type nécessite des arguments de constructeur ou est plus efficace avec des arguments de constructeur.
la source
La vraie différence se résume à la façon dont le compilateur gcc génère le code machine et installe la mémoire. Explique:
Il existe certainement d'autres façons de gérer les membres de type const. Mais pour faciliter leur vie, les auteurs du compilateur gcc décident de mettre en place des règles
la source
Il n'y a qu'une seule façon d' initialiser les instances de classe de base et les variables de membre non statiques et qui utilise la liste d'initialisation.
Si vous ne spécifiez pas de variable membre de base ou non statique dans la liste d'initialisation de votre constructeur, ce membre ou cette base sera initialisé par défaut (si le membre / base est un type de classe non-POD ou un tableau de classe non-POD types) ou laissés non initialisés dans le cas contraire.
Une fois le corps du constructeur entré, toutes les bases ou tous les membres auront été initialisés ou laissés non initialisés (c'est-à-dire qu'ils auront une valeur indéterminée). Il n'y a aucune possibilité dans le corps du constructeur d'influencer la façon dont ils doivent être initialisés.
Vous pourrez peut-être attribuer de nouvelles valeurs aux membres dans le corps du constructeur, mais il n'est pas possible d'affecter des
const
membres ou des membres de type classe qui ont été rendus non assignables et il n'est pas possible de relier les références.Pour les types intégrés et certains types définis par l'utilisateur, l'affectation dans le corps du constructeur peut avoir exactement le même effet que l'initialisation avec la même valeur dans la liste d'initialisation.
Si vous ne parvenez pas à nommer un membre ou une base dans une liste d'initialiseurs et que cette entité est une référence, a un type de classe sans constructeur par défaut déclaré par l'utilisateur accessible, est
const
qualifiée et a un type POD ou est un type de classe POD ou un tableau de type de classe POD contenant unconst
membre qualifié (directement ou indirectement) alors le programme est mal formé.la source
Si vous écrivez une liste d'initialiseurs, vous faites tout en une seule étape; si vous n'écrivez pas de liste d'initiateurs, vous ferez 2 étapes: une pour la déclaration et une pour attribuer la valeur.
la source
Il existe une différence entre la liste d'initialisation et l'instruction d'initialisation dans un constructeur. Considérons le code ci-dessous:
Lorsque MyClass est utilisé, tous les membres seront initialisés avant la première instruction dans un constructeur exécuté.
Mais, lorsque MyClass2 est utilisé, tous les membres ne sont pas initialisés lorsque la première instruction d'un constructeur est exécutée.
Dans un cas ultérieur, il peut y avoir un problème de régression lorsque quelqu'un a ajouté du code dans un constructeur avant qu'un certain membre ne soit initialisé.
la source
Voici un point que je n'ai pas vu d'autres y faire référence:
La classe temporaire n'a pas de cteur par défaut. Lorsque nous l'utilisons dans une autre classe comme suit:
le code ne compilera pas, car le compilateur ne sait pas comment initialiser
obj
, car il a juste un ctor explicite qui reçoit une valeur int, nous devons donc changer le ctor comme suit:Donc, il ne s'agit pas seulement de const et de références!
la source