Jusqu'où allez-vous const
? Faites-vous simplement des fonctions const
lorsque cela est nécessaire ou allez-vous tout le porc et utilisez-le partout? Par exemple, imaginez un simple mutateur qui prend un seul paramètre booléen:
void SetValue(const bool b) { my_val_ = b; }
Est-ce const
vraiment utile? Personnellement, je choisis de l'utiliser largement, y compris les paramètres, mais dans ce cas, je me demande si cela en vaut la peine?
J'ai également été surpris d'apprendre que vous pouvez omettre const
des paramètres dans une déclaration de fonction mais pouvez l'inclure dans la définition de la fonction, par exemple:
fichier .h
void func(int n, long l);
Fichier .cpp
void func(const int n, const long l)
Y a-t-il une raison à cela? Cela me semble un peu inhabituel.
Réponses:
La raison en est que const pour le paramètre ne s'applique que localement dans la fonction, car il travaille sur une copie des données. Cela signifie que la signature de fonction est de toute façon la même. C'est probablement un mauvais style de faire beaucoup de choses.
Personnellement, j'ai tendance à ne pas utiliser const, sauf pour les paramètres de référence et de pointeur. Pour les objets copiés, cela n'a pas vraiment d'importance, bien qu'il puisse être plus sûr car il signale l'intention dans la fonction. C'est vraiment un appel au jugement. J'ai tendance à utiliser const_iterator quand je boucle sur quelque chose et je n'ai pas l'intention de le modifier, donc je suppose que chacun le sien, tant que l'exactitude de const pour les types de référence est rigoureusement maintenue.
la source
const
des prototypes de fonction présente l'avantage de ne pas avoir à modifier le fichier d'en-tête si vous décidez de supprimer laconst
partie d'implémentation ultérieurement.const
là où cela fait une différence utile».const
chaque fois que possible; c'est plus expressif. Quand je lis le code de quelqu'un d'autre, j'utilise de petits indicateurs comme celui-ci pour juger du soin qu'ils mettent à écrire leur code à côté de choses comme les nombres magiques, les commentaires et l'utilisation appropriée du pointeur, etc.int getDouble(int a){ ++a; return 2*a; }
Essaye ça. Bien sûr, le++a
n'a rien à faire là-bas mais on peut le trouver dans une longue fonction écrite par plus d'un programmeur sur une longue période de temps. Je suggère fortement d'écrireint getDouble( const int a ){ //... }
qui générera une erreur de compilation lors de la recherche++a;
.class Foo { int multiply(int a, int b) const; }
dans votre en-tête. Dans votre mise en œuvre, vous vous souciez de pouvoir promettre de ne pas modifiera
et estb
doncint Foo::multiply(const int a, const int b) const { }
logique ici. (Sidenote: l'appelant et l'implémentation se soucient du fait que la fonction ne modifie pas sonFoo
objet, donc le const à la fin de sa déclaration)"const est inutile lorsque l'argument est passé par valeur car vous ne modifierez pas l'objet de l'appelant."
Faux.
Il s'agit d'auto-documenter votre code et vos hypothèses.
Si votre code a beaucoup de gens qui travaillent dessus et que vos fonctions ne sont pas triviales, vous devez marquer "const" tout ce que vous pouvez. Lorsque vous écrivez du code de force industrielle, vous devez toujours supposer que vos collègues sont des psychopathes qui essaient de vous aider de toutes les manières possibles (d'autant plus que c'est souvent vous-même à l'avenir).
En outre, comme quelqu'un l'a mentionné plus tôt, cela pourrait aider le compilateur à optimiser un peu les choses (bien que ce soit un long terme).
la source
Parfois (trop souvent!) Je dois démêler le code C ++ de quelqu'un d'autre. Et nous savons tous que le code C ++ de quelqu'un d'autre est un gâchis complet presque par définition :) Donc la première chose que je fais pour déchiffrer le flux de données local est de mettre const dans chaque définition de variable jusqu'à ce que le compilateur commence à aboyer. Cela signifie également des arguments de valeur de qualification de const, car ce ne sont que de fantastiques variables locales initialisées par l'appelant.
Ah, je souhaite que les variables soient const par défaut et qu'elles mutables pour les variables non const :)
la source
[x](){return ++x;}
est une erreur; voir iciconst
" par défaut dans Rust :)Les deux lignes suivantes sont fonctionnellement équivalentes:
De toute évidence, vous ne pourrez pas modifier
a
le corps defoo
si c'est défini de la deuxième façon, mais il n'y a pas de différence de l'extérieur.Ce
const
qui est vraiment utile avec les paramètres de référence ou de pointeur:Cela signifie que foo peut prendre un grand paramètre, peut-être une structure de données de taille gigaoctet, sans la copier. En outre, il dit à l'appelant: "Foo ne changera pas le contenu de ce paramètre." La transmission d'une référence const permet également au compilateur de prendre certaines décisions en matière de performances.
*: A moins qu'il ne rejette la constance, mais c'est un autre post.
la source
Les constats superflus sont mauvais du point de vue de l'API:
Mettre des constants superflus supplémentaires dans votre code pour les paramètres de type intrinsèque transmis par la valeur encombre votre API sans faire de promesse significative à l'appelant ou à l'utilisateur de l'API (cela ne fait que gêner la mise en œuvre).
Trop de «const» dans une API quand ils ne sont pas nécessaires, c'est comme « pleurer le loup », finalement les gens commenceront à ignorer «const» parce qu'il est partout et ne veut rien dire la plupart du temps.
L'argument "reductio ad absurdum" pour les consts supplémentaires dans l'API est bon pour ces deux premiers points serait que si plus de paramètres const sont bons, alors chaque argument qui peut avoir un const dessus, DEVRAIT avoir un const dessus. En fait, si c'était vraiment bon, vous voudriez que const soit la valeur par défaut pour les paramètres et ayez un mot-clé comme "mutable" uniquement lorsque vous voulez changer le paramètre.
Essayons donc de mettre const partout où nous pouvons:
Considérez la ligne de code ci-dessus. Non seulement la déclaration est plus encombrée et plus longue et plus difficile à lire, mais trois des quatre mots clés «const» peuvent être ignorés en toute sécurité par l'utilisateur de l'API. Cependant, l'utilisation supplémentaire de «const» a rendu la deuxième ligne potentiellement DANGEREUSE!
Pourquoi?
Une mauvaise lecture rapide du premier paramètre
char * const buffer
pourrait vous faire penser qu'il ne modifiera pas la mémoire dans le tampon de données qui est passé - cependant, ce n'est pas vrai!Un «const» superflu peut conduire à des hypothèses dangereuses et incorrectes sur votre API lorsqu'il est analysé ou mal lu rapidement.Les constats superflus sont également mauvais du point de vue de l'implémentation du code:
Si FLEXIBLE_IMPLEMENTATION n'est pas vrai, alors l'API «promet» de ne pas implémenter la fonction de la première manière ci-dessous.
C'est une promesse très stupide à faire. Pourquoi devriez-vous faire une promesse qui n'apporte aucun avantage à votre appelant et limite seulement votre mise en œuvre?
Les deux sont des implémentations parfaitement valides de la même fonction, donc tout ce que vous avez fait est lié inutilement une main derrière votre dos.
De plus, c'est une promesse très superficielle qui est facilement (et juridiquement contournable).
Écoutez, je l'ai implémenté de cette façon de toute façon, même si j'ai promis de ne pas le faire - en utilisant simplement une fonction wrapper. C'est comme quand le méchant promet de ne pas tuer quelqu'un dans un film et ordonne à son homme de main de le tuer à la place.
Ces constantes superflues ne valent rien de plus qu'une promesse d'un méchant de film.
Mais la capacité de mentir devient encore pire:
J'ai été informé que vous pouvez ne pas faire correspondre const dans l'en-tête (déclaration) et le code (définition) en utilisant un faux const. Les défenseurs const-happy affirment que c'est une bonne chose car cela vous permet de mettre const uniquement dans la définition.
Cependant, l'inverse est vrai ... vous ne pouvez mettre une constante parasite que dans la déclaration et l'ignorer dans la définition. Cela ne fait que constuire superflu dans une API plus une chose terrible et un mensonge horrible - voir cet exemple:
En fait, tout ce qui est superflu est de rendre le code de l'implémentateur moins lisible en l'obligeant à utiliser une autre copie locale ou une fonction d'encapsuleur quand il veut changer la variable ou passer la variable par référence non const.
Regardez cet exemple. Quel est le plus lisible? Est-il évident que la seule raison de la variable supplémentaire dans la deuxième fonction est que certains concepteurs d'API ont ajouté une constante superflue?
J'espère que nous avons appris quelque chose ici. La constance superflue est une horreur encombrante, un bourrin ennuyeux, une promesse superficielle et dénuée de sens, un obstacle inutile, et conduit parfois à des erreurs très dangereuses.
la source
void foo(int)
et avoid foo(const int)
exactement la même fonction, pas les surcharges. ideone.com/npN4W4 ideone.com/tZav9R La const ici n'est qu'un détail d'implémentation du corps de la fonction, et n'a aucun effet sur la résolution de surcharge. Laissez const hors de la déclaration, pour une API plus sûre et plus nette, mais mettez const dans la définition , si vous avez l'intention de ne pas modifier la valeur copiée.pi++
quand ils ne sont pas censés le faire.const aurait dû être la valeur par défaut en C ++. Comme ça :
la source
unsigned
aurait dû être la valeur par défaut en C ++. Comme ça:int i = 5; // i is unsigned
etsigned int i = 5; // i is signed
.Quand j'ai codé C ++ pour gagner ma vie, j'ai consterné tout ce que je pouvais. L'utilisation de const est un excellent moyen d'aider le compilateur à vous aider. Par exemple, la constance des valeurs de retour de votre méthode peut vous éviter des fautes de frappe telles que:
quand tu voulais dire:
Si foo () est défini pour renvoyer une référence non constante:
Le compilateur vous laissera volontiers attribuer une valeur au temporaire anonyme renvoyé par l'appel de fonction. Faire const:
Élimine cette possibilité.
la source
foo() = 42
: erreur: lvalue requise comme opérande gauche de l'affectationconst int foo()
est d'un type différent deint foo()
, ce qui vous pose de gros problèmes si vous utilisez des choses comme des pointeurs de fonction, des systèmes de signal / slot ou boost :: bind.const int& foo()
effectivement le même queint foo()
, en raison de l'optimisation de la valeur de retour?Il y a une bonne discussion sur ce sujet dans les anciens articles du "Gourou de la semaine" sur comp.lang.c ++. Modérés ici .
L'article GOTW correspondant est disponible sur le site Web de Herb Sutter ici .
la source
Je dis const vos paramètres de valeur.
Considérez cette fonction de buggy:
Si le paramètre numérique était const, le compilateur s'arrêterait et nous avertirait du bogue.
la source
J'utilise const sur des paramètres de fonction qui sont des références (ou des pointeurs) qui ne sont que des données [in] et ne seront pas modifiées par la fonction. Signification, lorsque le but d'utiliser une référence est d'éviter la copie de données et de ne pas permettre de changer le paramètre passé.
Mettre const sur le paramètre booléen b dans votre exemple ne fait que mettre une contrainte sur l'implémentation et ne contribue pas à l'interface de la classe (bien qu'il ne soit généralement pas conseillé de changer les paramètres).
La signature de fonction pour
et
est le même, ce qui explique votre .c et .h
Asaf
la source
Si vous utilisez les opérateurs
->*
ou.*
, c'est un must.Cela vous empêche d'écrire quelque chose comme
ce que j'ai presque fait en ce moment, et qui ne fait probablement pas ce que vous voulez.
Ce que je voulais dire était
et si j'avais mis un
const
entreBar *
etp
, le compilateur me l'aurait dit.la source
Ah, difficile. D'un côté, une déclaration est un contrat et cela n'a vraiment aucun sens de passer un argument const par valeur. D'un autre côté, si vous regardez l'implémentation de la fonction, vous donnez au compilateur plus de chances d'optimiser si vous déclarez un argument constant.
la source
const est inutile lorsque l'argument est passé par valeur car vous ne modifierez pas l'objet de l'appelant.
const doit être préféré lors du passage par référence, sauf si le but de la fonction est de modifier la valeur passée.
Enfin, une fonction qui ne modifie pas l'objet courant (this) peut, et devrait probablement être déclarée const. Un exemple est ci-dessous:
Il s'agit d'une promesse de ne pas modifier l'objet auquel cet appel est appliqué. En d'autres termes, vous pouvez appeler:
Si la fonction n'était pas const, cela entraînerait un avertissement du compilateur.
la source
Marquer les paramètres de valeur «const» est définitivement une chose subjective.
Cependant, je préfère marquer les paramètres de valeur const, comme dans votre exemple.
Pour moi, la valeur indique clairement que les valeurs des paramètres de fonction ne sont jamais modifiées par la fonction. Ils auront la même valeur au début qu'à la fin. Pour moi, cela fait partie du maintien d'un style de programmation très fonctionnel.
Pour une fonction courte, c'est sans doute une perte de temps / d'espace d'avoir le «const», car il est généralement assez évident que les arguments ne sont pas modifiés par la fonction.
Cependant, pour une fonction plus grande, c'est une forme de documentation d'implémentation, et elle est appliquée par le compilateur.
Je peux être sûr que si je fais un calcul avec 'n' et 'l', je peux refactoriser / déplacer ce calcul sans craindre d'obtenir un résultat différent parce que j'ai raté un endroit où l'un ou les deux sont modifiés.
Comme il s'agit d'un détail d'implémentation, vous n'avez pas besoin de déclarer les paramètres de valeur const dans l'en-tête, tout comme vous n'avez pas besoin de déclarer les paramètres de fonction avec les mêmes noms que ceux utilisés par l'implémentation.
la source
Peut-être que ce ne sera pas un argument valable. mais si nous incrémentons la valeur d'une variable const à l'intérieur d'un compilateur de fonctions, nous obtiendrons une erreur: " erreur: incrémentation du paramètre en lecture seule ". ce qui signifie que nous pouvons utiliser le mot clé const comme un moyen d'empêcher de modifier accidentellement nos variables à l'intérieur des fonctions (que nous ne sommes pas censés / en lecture seule). donc si nous l'avons accidentellement fait au moment de la compilation, le compilateur nous le fera savoir. c'est particulièrement important si vous n'êtes pas le seul à travailler sur ce projet.
la source
J'ai tendance à utiliser const autant que possible. (Ou tout autre mot clé approprié pour la langue cible.) Je le fais uniquement parce qu'il permet au compilateur de faire des optimisations supplémentaires qu'il ne pourrait pas faire autrement. Comme je n'ai aucune idée de ce que peuvent être ces optimisations, je le fais toujours, même là où cela semble idiot.
Pour autant que je sache, le compilateur pourrait très bien voir un paramètre de valeur const et dire: "Hé, cette fonction ne le modifie pas de toute façon, donc je peux passer par référence et enregistrer quelques cycles d'horloge." Je ne pense pas que cela ferait jamais une telle chose, car cela change la signature de la fonction, mais cela fait le point. Peut-être que cela fait une manipulation de pile différente ou quelque chose ... Le fait est que je ne sais pas, mais je sais qu'essayer d'être plus intelligent que le compilateur ne fait que me faire honte.
C ++ a des bagages supplémentaires, avec l'idée de const-correctness, donc cela devient encore plus important.
la source
const
. Il s'agit plutôt d'indiquer l'intention au sein de l'implémentation et de rattraper les penseurs plus tard (incrémenter accidentellement la mauvaise variable locale, car ce n'était pas le casconst
). Parallèlement, j'ajouterais également que les compilateurs sont les bienvenus pour modifier les signatures de fonction, dans le sens où les fonctions peuvent être intégrées, et une fois intégrées, la façon dont elles fonctionnent peut être modifiée; l'ajout ou la suppression de références, la création de littéraux de «variables», etc. sont tous dans la règle comme si1. Meilleure réponse basée sur mon évaluation:
La réponse de @Adisak est la meilleure réponse ici basée sur mon évaluation. Notez que cette réponse est en partie la meilleure car elle est également la plus bien sauvegardée avec de vrais exemples de code , en plus d'utiliser une logique saine et bien pensée.
2. Mes propres mots (en accord avec la meilleure réponse):
const
. Il ne fait que:const
partout peut entraver cela.const
encombre inutilement le code avecconst
s partout, détournant l'attention desconst
s qui sont vraiment nécessaires pour avoir un code sûr.const
est extrêmement important en cas de besoin, et doit être utilisé, car il empêche les effets secondaires indésirables avec des changements persistants en dehors de la fonction, et donc chaque pointeur ou référence doit utiliserconst
lorsque le parm est une entrée uniquement, pas une sortie. L'utilisationconst
uniquement de paramètres passés par référence ou par pointeur a l'avantage supplémentaire de rendre vraiment évident quels paramètres sont des pointeurs ou des références. C’est une chose de plus que de s’exprimer et de dire "Attention!const
côté de lui est une référence ou un pointeur!".3. Les mots de Google (d'accord avec moi et la meilleure réponse):
(Extrait du " Google C ++ Style Guide ")
Source: section "Utilisation de const" du Guide de style Google C ++: https://google.github.io/styleguide/cppguide.html#Use_of_const . Il s'agit en fait d'une section très utile, alors lisez toute la section.
Notez que "TotW # 109" signifie "Astuce de la semaine # 109: Significatif
const
dans les déclarations de fonction" , et est également une lecture utile. Il est plus informatif et moins normatif sur ce qu'il faut faire, et basé sur le contexte avant la règle du guide de style Google C ++const
citée ci-dessus, mais en raison de la clarté qu'il a fournie, laconst
règle citée ci-dessus a été ajoutée au Google C ++ Guide de style.Notez également que même si je cite le guide de style Google C ++ ici pour défendre ma position, cela ne signifie PAS que je suis toujours le guide ou que je recommande toujours de le suivre. Certaines des choses qu'ils recommandent sont tout simplement étranges, comme leur
kDaysInAWeek
convention de dénomination -style pour les "noms constants" . Cependant, il est toujours utile et pertinent de souligner quand l'une des sociétés techniques et logicielles les plus performantes et les plus influentes au monde utilise la même justification que moi et d'autres comme @Adisak pour étayer nos points de vue sur cette question.4. Linter de Clang,
clang-tidy
, a quelques options pour cela:R. Il est également intéressant de noter que le linter de Clang,
clang-tidy
a une option,readability-avoid-const-params-in-decls
, décrite ici , pour soutenir l' application dans une base de code non en utilisantconst
des paramètres de fonction passe par valeur :Et voici deux autres exemples que j'ajoute moi-même pour être complet et clair:
B. Il a également cette option:
readability-const-return-type
- https://clang.llvm.org/extra/clang-tidy/checks/readability-const-return-type.html5. Mon approche pragmatique de la façon dont je rédigerais un guide de style sur la question:
Je voudrais simplement copier et coller ceci dans mon guide de style:
[COPY / PASTE START]
const
les paramètres de fonction passés par référence ou par pointeur lorsque leur contenu (vers quoi ils pointent) ne doit PAS être modifié. De cette façon, il devient évident lorsqu'une variable passée par référence ou pointeur EST censée être modifiée, car elle manqueraconst
. Dans ce cas d'utilisation,const
prévient les effets secondaires accidentels en dehors de la fonction.const
sur les paramètres de fonction passés par valeur, carconst
n'a aucun effet sur l'appelant: même si la variable est modifiée dans la fonction, il n'y aura pas d'effets secondaires en dehors de la fonction. Voir les ressources suivantes pour une justification et des informations supplémentaires:const
déclarations de fonctions significatives "const
[c'est -à- dire:const
sur des paramètres passés par valeur ] sur des paramètres de fonction dans des déclarations qui ne sont pas des définitions (et faites attention à ne pas copier / coller un sensconst
). Il est vide de sens et ignoré par le compilateur, c'est du bruit visuel , et cela pourrait induire les lecteurs en erreur "( https://abseil.io/tips/109 , je souligne).const
qualificatifs qui ont un effet sur la compilation sont ceux placés dans la définition de fonction, PAS ceux dans une déclaration avant de la fonction, comme dans une déclaration de fonction (méthode) dans un fichier d'en-tête.const
[c'est -à- dire:const
sur des variables passées par valeur ] sur des valeurs renvoyées par une fonction.const
de pointeurs ou de références retournés par une fonction dépend de l'implémenteur , car elle est parfois utile.clang-tidy
options ci-dessus avec les options suivantes :Voici quelques exemples de code pour illustrer les
const
règles décrites ci-dessus:const
Exemples de paramètres:(certains sont empruntés d' ici )
const
Exemples de type de retour:(certains sont empruntés d' ici )
[FIN COPIE / COLLAGE]
la source
Dans le cas que vous mentionnez, cela n'affecte pas les appelants de votre API, c'est pourquoi cela n'est pas courant (et n'est pas nécessaire dans l'en-tête). Cela n'affecte que la mise en œuvre de votre fonction.
Ce n'est pas particulièrement une mauvaise chose à faire, mais les avantages ne sont pas si grands étant donné que cela n'affecte pas votre API et qu'il ajoute de la frappe, donc ce n'est généralement pas fait.
la source
Je n'utilise pas const pour les paramètres à valeur transmise. L'appelant ne se soucie pas de savoir si vous modifiez le paramètre ou non, c'est un détail d'implémentation.
Ce qui est vraiment important, c'est de marquer les méthodes comme const si elles ne modifient pas leur instance. Faites cela au fur et à mesure, sinon vous pourriez vous retrouver avec beaucoup de const_cast <> ou vous pourriez constater que le marquage d'une méthode const nécessite de changer beaucoup de code car il appelle d'autres méthodes qui auraient dû être marquées const.
J'ai également tendance à marquer les variables locales si je n'ai pas besoin de les modifier. Je crois que cela rend le code plus facile à comprendre en facilitant l'identification des "parties mobiles".
la source
Sur les optimisations du compilateur: http://www.gotw.ca/gotw/081.htm
la source
J'utilise const où je peux. Const pour les paramètres signifie qu'ils ne doivent pas changer leur valeur. Ceci est particulièrement utile lors du passage par référence. const for function déclare que la fonction ne doit pas changer les membres des classes.
la source
Résumer:
std::vector::at(size_type pos)
. Ce qui est assez bon pour la bibliothèque standard est bon pour moi.la source
_Tmp
tout le temps - vous ne voulez pas cela (en fait, vous n'êtes pas autorisé à les utiliser).Si le paramètre est passé par valeur (et n'est pas une référence), il n'y a généralement pas beaucoup de différence que le paramètre soit déclaré const ou non (sauf s'il contient un membre de référence - pas un problème pour les types intégrés). Si le paramètre est une référence ou un pointeur, il est généralement préférable de protéger la mémoire référencée / pointée, pas le pointeur lui-même (je pense que vous ne pouvez pas faire de la référence elle-même une const, pas que cela ait beaucoup d'importance car vous ne pouvez pas changer l'arbitre) . Il semble une bonne idée de protéger tout ce que vous pouvez en tant que const. Vous pouvez l'omettre sans craindre de faire une erreur si les paramètres ne sont que des POD (y compris les types intégrés) et qu'il n'y a aucune chance qu'ils changent plus loin sur la route (par exemple dans votre exemple le paramètre bool).
Je ne connaissais pas la différence de déclaration de fichier .h / .cpp, mais cela a du sens. Au niveau du code machine, rien n'est "const", donc si vous déclarez une fonction (dans le .h) non-const, le code est le même que si vous la déclarez const (optimisations mises à part). Cependant, cela vous aide à enrôler le compilateur pour ne pas modifier la valeur de la variable dans l'implémentation de la fonction (.ccp). Cela peut être utile dans le cas où vous héritez d'une interface qui permet le changement, mais vous n'avez pas besoin de changer de paramètre pour obtenir la fonctionnalité requise.
la source
Je ne mettrais pas const sur des paramètres comme ça - tout le monde sait déjà qu'un booléen (par opposition à un booléen &) est constant, donc l'ajouter fera faire penser aux gens "attendez, quoi?" ou même que vous passez le paramètre par référence.
la source
la chose à retenir avec const est qu'il est beaucoup plus facile de rendre les choses const dès le début, que d'essayer de les mettre plus tard.
Utilisez const lorsque vous voulez que quelque chose reste inchangé - c'est un indice supplémentaire qui décrit ce que fait votre fonction et à quoi s'attendre. J'ai vu de nombreuses API C qui pourraient faire avec certaines d'entre elles, en particulier celles qui acceptent les chaînes C!
Je serais plus enclin à omettre le mot clé const dans le fichier cpp que l'en-tête, mais comme j'ai tendance à les couper + coller, ils seraient conservés aux deux endroits. Je ne sais pas pourquoi le compilateur permet cela, je suppose que c'est une chose de compilateur. La meilleure pratique est certainement de mettre votre mot-clé const dans les deux fichiers.
la source
Il n'y a vraiment aucune raison de créer un paramètre de valeur "const" car la fonction ne peut de toute façon que modifier une copie de la variable.
La raison d'utiliser "const" est si vous passez quelque chose de plus grand (par exemple une structure avec beaucoup de membres) par référence, auquel cas cela garantit que la fonction ne peut pas la modifier; ou plutôt, le compilateur se plaindra si vous essayez de le modifier de la manière conventionnelle. Cela l'empêche d'être modifié accidentellement.
la source
Le paramètre const n'est utile que lorsque le paramètre est transmis par référence, c'est-à-dire par référence ou par pointeur. Lorsque le compilateur voit un paramètre const, il s'assure que la variable utilisée dans le paramètre n'est pas modifiée dans le corps de la fonction. Pourquoi voudrait-on rendre constant un paramètre de valeur? :-)
la source
const
indique clairement: «Je n'ai pas besoin de modifier cela, donc je le déclare. Si j'essaye de le modifier plus tard, donnez-moi une erreur au moment de la compilation afin que je puisse corriger mon erreur ou annuler le marquageconst
. ' C'est donc une question d'hygiène et de sécurité du code. Pour tout ce qu'il faut pour ajouter aux fichiers d'implémentation, cela devrait être quelque chose que les gens font comme un pur réflexe, l'OMI.Étant donné que les paramètres sont transmis par valeur, cela ne fait aucune différence si vous spécifiez const ou non du point de vue de la fonction appelante. Cela n'a en fait aucun sens de déclarer les paramètres de passage par valeur comme const.
la source
Tous les consts dans vos exemples n'ont aucun sens. C ++ est transmis par valeur par défaut, donc la fonction obtient des copies de ces entiers et booléens. Même si la fonction les modifie, la copie de l'appelant n'est pas affectée.
J'éviterais donc des consts supplémentaires parce que
la source
Je sais que la question est "un peu" dépassée, mais au fur et à mesure que je l'ai rencontrée, quelqu'un d'autre peut aussi le faire à l'avenir ... ... je doute encore que le pauvre garçon énumérera ici pour lire mon commentaire :)
Il me semble que nous sommes encore trop cantonnés à une pensée de type C. Dans le paradigme OOP, nous jouons avec des objets, pas avec des types. L'objet const peut être conceptuellement différent d'un objet non const, en particulier dans le sens de logique-const (contrairement à bitwise-const). Ainsi, même si l'exactitude constante des paramètres de fonction est (peut-être) une prudence excessive dans le cas des POD, elle ne l'est pas dans le cas des objets. Si une fonction fonctionne avec un objet const, elle doit le dire. Considérez l'extrait de code suivant
ps.: vous pouvez affirmer que la référence (const) serait plus appropriée ici et vous donne le même comportement. Et bien. Juste donner une image différente de ce que je pouvais voir ailleurs ...
la source