Cette macro peut être définie dans un en-tête global, ou mieux, en tant que paramètre de ligne de commande du compilateur:
#define me (*this)
Et un exemple d'utilisation:
some_header.h:
inline void Update()
{
/* ... */
}
main.cpp:
#include "some_header.h"
class A {
public:
void SetX(int x)
{
me.x = x;
me.Update();
}
void SomeOtherFunction()
{
::Update();
}
/*
100 or more lines
...
*/
void Update()
{
// ...
}
int x;
};
Ainsi, dans une méthode de classe lorsque j'accède à un membre de la classe, j'utilise toujours me
et lorsque j'accède à un identifiant global, j'utilise toujours ::
. Cela donne au lecteur qui n'est pas familier avec le code (probablement moi-même après quelques mois) des informations localisées de ce qui est accessible sans avoir besoin de chercher ailleurs. Je veux définir me
car je trouve l'utilisation this->
partout trop bruyante et laide. Mais peut- #define me (*this)
on considérer comme une bonne pratique C ++? Y a-t-il des points pratiques problématiques avec la me
macro? Et si vous, en tant que programmeur C ++, serez le lecteur de code à l'aide de la me
macro, cela vous plaira ou non?
Edit: Parce que beaucoup de gens ne soutiennent pas spécifiquement contre l'utilisation me
, mais contre expliquent généralement cela. Je pense qu'il n'est peut-être pas clair quels sont les avantages de «l'expliciter partout».
Quels sont les avantages de "l'expliciter partout"?
- En tant que lecteur du code, vous avez la certitude de ce qui est accédé et vous pouvez vous concentrer sur des choses différentes que de vérifier - dans un code distant - que vous avez réellement accès à ce que vous pensez être accédé.
- Vous pouvez utiliser la fonction de recherche plus spécifiquement. La recherche "
this->x
" peut vous donner plus de résultats que la recherche "x
" - Lorsque vous supprimez ou renommez un membre, le compilateur vous avertit de manière fiable aux endroits où ce membre est utilisé. (Certaines fonctions globales peuvent avoir le même nom et exister, vous pouvez introduire une erreur si vous n'utilisez pas cela explicitement).
- Lorsque vous refactorisez du code et rendez explicite la fonction non membre à partir d'un membre (pour une meilleure encapsulation), cela vous montre où vous devez modifier et vous pouvez facilement le remplacer par un pointeur sur l'instance de classe donnée comme paramètre de fonction non membre
- Généralement, lorsque vous modifiez du code, il y a plus de possibilités d'erreurs lorsque vous n'utilisez pas cela explicitement que lorsque vous utilisez cela explicitement partout.
- Explicite, c'est moins bruyant que «m_» explicite lorsque vous accédez à un membre de l'extérieur (
object.member
vsobject.m_member
) (merci à @Kaz de repérer ce point) - Explicitement, cela résout le problème universellement pour tous les membres - attributs et méthodes, alors que «m_» ou un autre préfixe n'est pratiquement utilisable que pour les attributs.
Je voudrais peaufiner et étendre cette liste, dites-moi si vous connaissez d'autres avantages et utilisez des cas pour l'expliquer partout .
#define self (*this)
? Vous pouvez même mélanger les deux macros et avoir certains fichiers imitant VB et d'autres Python. :)#include "vb.h"
,#Include pascal.h
ou#include FOTRAN.h
et ont la prochaine personne à toucher votre code soumettre à TDWTF .me_x
.Réponses:
Non, ça ne l'est pas.
Attention au programmeur qui maintiendra votre code plusieurs années à partir de maintenant longtemps après votre départ pour des pâturages plus verts et suivra les conventions courantes du langage que vous utilisez. En C ++, vous n'avez presque jamais à écrire
this
, car la classe est incluse dans l'ordre de résolution des symboles et lorsqu'un symbole est trouvé dans la portée de la classe, celathis->
est implicite. Donc, ne l'écrivez pas comme tout le monde.Si vous confondez souvent les symboles provenant de la portée de la classe, l'approche habituelle consiste à utiliser un modèle de dénomination commun pour les membres (champs et méthodes parfois privées; je ne l'ai pas vu utilisé pour les méthodes publiques). Les plus courants incluent le suffixe avec
_
ou le préfixe avecm_
oum
.la source
this
pour indiquer clairement que la variable n'est pas locale à la méthode. La question ici est de savoir si la macrome
doit exister, et non sithis
quelque chose doit être utilisé.me.
place dethis->
. Comme il n'y a pas besoin de,this->
il n'y a pas besoinme.
et donc pas besoin de la macro.this->
"est nécessaire". En fait, le PO dit qu'il utilisethis->
malgré le fait que ce ne soit pas nécessaire. La question est de savoir si elleme.
doit être utilisée à la place dethis->
, à laquelle cette réponse ne répond pas réellement.this
et donc une discussion sur ce point est nécessaire pour parvenir à une conclusion pleinement équilibrée.Donc, vous voulez créer une nouvelle langue. Faites-le ensuite et ne paralysez pas C ++.
Il y a plusieurs raisons de ne pas le faire:
this
c'est, et en ajoutant une telle macro, vous ajoutez en fait un nouveau mot-clé. Et si chacun présente quelque chose qu'il aime? À quoi ressemblerait le code?(*this).
ou pasthis->
du tout, sauf dans certains cas spéciaux (voir cette réponse et recherchez "this->")Votre code n'est pas différent de celui
#define R return
que j'ai vu dans le code réel. Raison? Moins de frappe!Aller légèrement hors sujet, mais ici je vais développer le point 3 (ne pas utiliser
(*this).
outhis->
en cours).Tout d'abord,
(*this).
outhis->
sont utilisés pour accéder aux variables membres ou aux fonctions de l'objet. Son utilisation n'a aucun sens et signifie plus de frappe. De plus, la lecture d'un tel code est plus difficile, car il y a plus de texte. Cela signifie un entretien plus difficile.Alors, quels sont les cas où vous devez utiliser
this->
?(a) Choix malheureux du nom de l'argument.
Dans cet exemple,
this->
est obligatoire, car l'argument a le même nom que la variable membre:(b) Lorsqu'il s'agit de modèles et d'héritage (voir ceci )
Cet exemple ne parviendra pas à compiler, car le compilateur ne sait pas à quelle variable nommée
v
accéder.la source
*this.
etthis->
this->
est aussi utile qu'enauto
pré-c ++ 11. En d'autres termes, cela augmente simplement le bruit du code.Je suggère de ne pas faire ça. Cela donne à un lecteur qui n'est pas familier avec votre macro un gros " WTF " chaque fois qu'il le voit. Le code n'est pas plus lisible lorsque l'on invente de "nouvelles conventions" par rapport à celles généralement acceptées sans aucun besoin réel.
Cela peut vous sembler vrai, peut-être parce que vous avez fait beaucoup de programmation dans les langages en utilisant le mot-clé
me
(Visual Basic, je suppose?). Mais en fait, il s'agit simplement de s'y habituer -this->
c'est assez court, et je pense que la plupart des programmeurs C ++ expérimentés seront en désaccord avec votre opinion. Et dans le cas ci-dessus, ni l'utilisationthis->
ni l'utilisation deme
n'est appropriée - vous obtenez le plus petit encombrement en omettant ces mots clés lors de l'accès aux membres de données à l'intérieur des fonctions membres.Si vous voulez que vos variables membres privées soient distinguées des variables locales, ajoutez quelque chose de lien
m_
comme préfixe, ou un trait de soulignement comme suffixe (mais comme vous pouvez le voir ici , même cette convention est "trop bruyante" pour beaucoup de gens).la source
_
devrait être suffixé ; en tant que préfixe, il est réservé aux symboles internes des bibliothèques standard et des extensions du fournisseur.__
(deux traits de soulignement) ou un trait de soulignement suivi d'une lettre majuscule. Un simple trait de soulignement suivi d'une lettre minuscule convient, tant qu'il n'est pas dans l'espace de noms global.Veuillez ne pas le faire! J'essaie de faire face à une grande base de code où les macros sont partout pour enregistrer la frappe. La mauvaise chose à redéfinir cela pour moi est que le préprocesseur le remplacera partout même lorsque cela n'est pas dans la portée / ne s'applique pas, par exemple une fonction autonome, votre collègue peut avoir une variable locale qui m'appelle ailleurs. . (s) il ne sera pas content de déboguer ... Vous finissez par avoir des macros que vous ne pouvez pas utiliser dans toutes les étendues.
la source
NON!
Imaginez la confusion qui se produira si quelqu'un # inclut cet en-tête, ne connaissant pas votre astuce, et ailleurs dans son fichier, il a une variable ou une fonction appelée "moi". Ils seraient horriblement confus par tout message d'erreur impénétrable qui serait imprimé.
la source