Lors de la lecture d'une fonction membre, il est absolument essentiel de savoir qui "possède" chaque variable pour en comprendre la signification. Dans une fonction comme celle-ci :
void Foo::bar( int apples )
{
int bananas = apples + grapes;
melons = grapes * bananas;
spuds += melons;
}
...il est assez facile de voir d'où viennent les pommes et les bananes, mais qu'en est-il du raisin, des melons et des patates ? Devons-nous regarder dans l'espace de noms global ? Dans la déclaration de la classe ? La variable est-elle un membre de cet objet ou un membre de la classe de cet objet ? Sans connaître la réponse à ces questions, vous ne pouvez pas comprendre le code. Et dans une fonction plus longue, même les déclarations de variables locales comme les pommes et les bananes peuvent se perdre dans la confusion.
L'ajout d'une étiquette cohérente pour les globales, les variables membres et les variables membres statiques (peut-être g_, m_ et s_ respectivement) clarifie instantanément la situation.
void Foo::bar( int apples )
{
int bananas = apples + g_grapes;
m_melons = g_grapes * bananas;
s_spuds += m_melons;
}
Il faudra peut-être s'y habituer au début, mais qu'est-ce qui ne l'est pas en programmation ? Il fut un jour où même { et } vous semblaient étranges. Et une fois que vous vous y êtes habitué, ils vous aident à comprendre le code beaucoup plus rapidement.
(Utiliser "this->" à la place de m_ a du sens, mais est encore plus long et visuellement perturbant. Je ne le vois pas comme une bonne alternative pour marquer toutes les utilisations des variables membres).
Une objection possible à l'argument ci-dessus serait d'étendre l'argument aux types. Il pourrait aussi être vrai que connaître le type d'une variable "est absolument essentiel pour comprendre la signification de la variable". Si c'est le cas, pourquoi ne pas ajouter un préfixe à chaque nom de variable qui identifie son type ? Avec cette logique, on aboutit à la notation hongroise. Mais beaucoup de gens trouvent la notation hongroise laborieuse, laide et peu utile.
void Foo::bar( int iApples )
{
int iBananas = iApples + g_fGrapes;
m_fMelons = g_fGrapes * iBananas;
s_dSpuds += m_fMelons;
}
Hongrois fait nous apprennent quelque chose de nouveau sur le code. Nous comprenons maintenant qu'il y a plusieurs casts implicites dans la fonction Foo::bar(). Le problème avec le code maintenant est que la valeur de l'information ajoutée par les préfixes hongrois est faible par rapport au coût visuel. Le système de types C++ comprend de nombreuses fonctionnalités qui permettent aux types de bien fonctionner ensemble ou de déclencher un avertissement ou une erreur du compilateur. Le compilateur nous aide à traiter les types - nous n'avons pas besoin de notation pour le faire. Nous pouvons déduire assez facilement que les variables de Foo::bar() sont probablement numériques, et si c'est tout ce que nous savons, c'est suffisant pour avoir une compréhension générale de la fonction. Par conséquent, l'intérêt de connaître le type précis de chaque variable est relativement faible. Pourtant, la laideur d'une variable comme "s_dSpuds" (ou même simplement "dSpuds") est grande. Ainsi, une analyse coût-bénéfice rejette la notation hongroise, alors que l'avantage de g_, s_ et m_ dépasse le coût aux yeux de nombreux programmeurs.
21 votes
Je le préfère ; dans les bases de code complexes, il peut être important de savoir quelles variables sont locales et lesquelles ne le sont pas. J'utilise généralement le préfixe plutôt que de forcer this-> qui, à mon avis, représente beaucoup de saisie supplémentaire et est facultatif (alors que le nommage vous forcera à le faire).
6 votes
Vous ne l'avez jamais vu en Ruby à cause de @ pour attribut, et de l'idiome qui consiste à générer des accesseurs de préférence à l'utilisation directe des attributs.
6 votes
Selon PEP 8 Les variables membres non publiques doivent être préfixées par un trait de soulignement en Python (exemple :
self._something = 1
).2 votes
La coloration syntaxique de l'éditeur ne devrait-elle pas être utilisée pour les identifier ?
4 votes
Vous avez bien vu l'équivalent de
this->member
dans le code Python. En Python, ce serait typiquementself.member
et ce n'est pas seulement une convention, c'est requis par la langue.1 votes
Cela peut être intéressant pour vous : github.com/isocpp/CppCoreGuidelines/blob/master/
0 votes
L'utilisation de
this->memberVar
n'est pas seulement une question de style. La norme C++ établit que les membres non dépendants ne sont pas recherchés dans les classes dépendantes. Cela signifie que si vous êtes dans une classe enfant et que vous essayez d'accéder à une variable membre définie dans un modèle de classe parent, vous devrez fournir un nom qualifié pour cette variable.BaseClass<FooBar>::memberVar
ou, si le type de la variable peut dépendre de l'instanciation spécifique, vous n'aurez pas d'autre choix que d'y accéder par l'instance de classe spécifique.this->memberVar
. Voir par exemple stackoverflow.com/a/24368629/4276112