C ++ - initialisation des variables dans l'en-tête par rapport au constructeur
Quant à la suivante, existe-il des raisons d'agir l'un sur l'autre ou sont-ils à peu près équivalent?
class Something
{
int m_a = 0;
};
vs
class Something
{
int m_a;
Something(int p_a);
};
Something::Something(int p_a):m_a(p_a){ ... };
source d'informationauteur Evan Ward
Vous devez vous connecter pour publier un commentaire.
Les deux extraits de code que vous avez posté sont pas tout à fait égale.
Ici, vous spécifiez la valeur d'initialisation, c'est à dire
0
au moment de la compilation.Et ici, vous le faites à moment de l'exécution (ou peut-être au moment de l'exécution), avec la valeur
p_a
ne sait pas jusqu'à ce que le constructeur est appelé.Le morceau de code suivant est plus près de votre premier exemple:
Ce que vous avez à considérer ici est que dans le premier cas, la valeur s'affiche directement dans la définition de classe. Cela peut créer une inutile de dépendance. Qu'advient-il si vous avez besoin de changer votre
0
à1
plus tard? Exposer directement la valeur dans la définition de la classe (et donc, en général, dans un fichier d'en-tête) peut causer de la recompilation de beaucoup de code dans les situations où l'autre forme de l'initialisation permettrait d'éviter, parce que laSomething::Something() : m_a(0)
partie sera soigneusement encapsulé dans un fichier source et de ne pas apparaître dans un fichier d'en-tête:Bien sûr, les avantages de la classe d'initialisation peut emportent largement sur cet inconvénient. Il dépend. Vous avez juste à garder à l'esprit.
La première forme est plus pratique si vous avez plus d'un constructeur (et les veux tous, pour initialiser le membre de la même façon), ou si vous n'avez pas besoin d'écrire autrement un constructeur.
La seconde est nécessaire si l'initialiser dépend des arguments du constructeur, ou est trop compliqué pour la classe d'initialisation; et peut-être mieux si le constructeur est compliqué de garder toutes l'initialisation dans un seul endroit. (Et c'est aussi nécessaire pour la prise en charge pré-C++11 compilateurs.)
La première forme est de nouveau à C++11 et donc, à ce moment n'est pas très bien pris en charge, surtout si vous avez besoin pour soutenir une variété d'anciens compilateurs.
Sinon, ils devraient être à peu près équivalent lorsqu'un compilateur C++11 est disponible.
D'élaborer sur Christian Hackl de réponse.
La première forme permet d'initialiser
m_a
et ont une valeur par défaut c'tor en même temps. Ou vous pouvez même être explicite dans votre code et de définir un constructeur avec ladefault
mot-clé:Avec la seconde forme, un auto-généré par défaut c'tor laisserait
m_a
non initialisée, donc si vous voulez initialiser à une valeur codée en dur, vous devez écrire votre propre défaut c'tor:est équivalent à
Donc, en faisant
donne une syntaxe uniforme pour l'initialisation qui nécessite ou ne nécessite pas de temps d'exécution entrée.
Personnellement je n'aime pas la première forme, car elle ressemble à une "déclaration de cession", qui est complètement fausse.
Même si c'est pris en charge, ce type de l'initialisation de créer des bugs qui vont être assez difficiles à dépister. C'est le type de "esthétique de l'optimisation" que vous allez le regretter quelques mois en bas de la route.
Voir l'exemple ci-dessous:
class_x_1.h:
class_x_2.h:
class_x.cpp:
main.cpp:
De sortie:
Comme prévu, il sera de retour 20 parce que c'est la version qui initialise x 20. Toutefois, si vous allez à la mise en œuvre de X, vous pourriez vous attendre à être 10.