Pour commencer, vous savez probablement que const
peut être utilisé pour rendre les données d'un objet ou un pointeur non modifiables, ou les deux.
const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer
Cependant, vous pouvez également utiliser la syntaxe:
Object const *obj; // same as const Object* obj;
La seule chose qui semble avoir de l'importance, c'est de quel côté de l'astérisque vous mettez le mot clé const
. Personnellement, je préfère mettre const
à gauche du type pour spécifier que ses données ne sont pas modifiables car je les trouve plus lisibles dans mon état d'esprit de gauche à droite, mais quelle syntaxe est apparue en premier?
Plus important encore, pourquoi existe-t-il deux manières correctes de spécifier des données const
et dans quelle situation préférez-vous ou avez-vous besoin de l'une plutôt que de l'autre?
Modifier:
Cela ressemble donc à une décision arbitraire lorsque la norme concernant l'interprétation des choses par les compilateurs a été rédigée bien avant ma naissance. Puisque const
est appliqué à ce qui est à gauche du mot clé (par défaut?), Je suppose qu’ils ont compris qu’il n’y avait aucun mal à ajouter "raccourcis" pour appliquer des mots clés et des qualificatifs de type dans autres moyens au moins jusqu’à ce que la déclaration change en analysant un * ou & ...
Ce fut le cas dans C aussi bien alors je suppose?
pourquoi existe-t-il deux manières correctes de spécifier des données
const
et dans quelle situation préférez-vous ou avez-vous besoin de l'une plutôt que de l'autre?
Pour l'essentiel, la position de const
dans les spécificateurs précédant un astérisque n'a pas d'importance, c'est que la grammaire C a été définie de cette manière par Kernighan et Ritchie.
La raison pour laquelle ils ont défini la grammaire de cette manière est probablement due au fait que leur compilateur C a analysé les entrées de gauche à droite et a fini de traiter chaque jeton au fur et à mesure de sa consommation. La consommation du jeton *
Modifie l'état de la déclaration en cours en un type de pointeur. Rencontrer const
après *
Signifie que le qualificateur const
est appliqué à une déclaration de pointeur; le rencontrer avant le *
signifie que le qualificatif est appliqué aux données pointées.
Comme la signification sémantique ne change pas si le qualificatif const
apparaît avant ou après les spécificateurs de type, il est accepté dans tous les cas.
Un cas similaire se présente lors de la déclaration de pointeurs de fonction, où:
void * function1(void)
déclare une fonction qui renvoie void *
,
void (* function2)(void)
déclare un pointeur de fonction à une fonction qui renvoie void
.
Encore une fois, la chose à noter est que la syntaxe du langage prend en charge un analyseur de gauche à droite.
La règle est la suivante:
const s'applique à la chose qui en reste. S'il n'y a rien à gauche, cela s'applique à la chose à droite.
Je préfère utiliser const sur la droite de la chose pour être const simplement parce que c'est la façon "originale" de définir const.
Mais je pense que c'est un point de vue très subjectif.
Je préfère la deuxième syntaxe. Cela m'aide à garder une trace de ce qui est constant en lisant la déclaration de type de droite à gauche:
Object * const obj; // read right-to-left: const pointer to Object
Object const * obj; // read right-to-left: pointer to const Object
Object const * const obj; // read right-to-left: const pointer to const Object
L'ordre des mots-clés dans une déclaration n'est pas tout à fait fixé. Il existe de nombreuses alternatives à "l'unique ordre véritable". Comme ça
int long const long unsigned volatile i = 0;
ou devrait-il être
volatile unsigned long long int const i = 0;
??
La première règle consiste à utiliser le format requis par vos normes de codage locales. Après cela: placer le const
devant vous évite toute confusion en cas de problèmes de typage, par exemple:
typedef int* IntPtr;
const IntPtr p1; // same as int* const p1;
Si votre norme de codage autorise la modification de type des pointeurs, il devrait insister pour que le paramètre const soit placé après le type. Dans tous les cas, mais lorsqu'il est appliqué au type, const doit suivre ce à quoi il s'applique, aussi la cohérence plaide-t-elle également en faveur de const après. Mais les directives de codage locales l'emportent sur toutes ces choses; normalement, la différence n'est pas assez importante pour revenir en arrière et modifier tout le code existant.
Il y a des raisons historiques que gauche ou droite est acceptable. Stroustrup avait ajouté const à C++ en 198 , mais ne parvint pas à C jusqu'à C89/C90.
En C++, il y a une bonne raison de toujours utiliser const à droite. Vous serez cohérent partout car les fonctions membres const doivent être déclarées de cette façon:
int getInt() const;