Quels sont les déficits connus de const code> en C ++ et c ++ 0x? p>
12 Réponses :
La seule chose qui ne va pas avec const code> est qu'il est
"Mais qu'est-ce qui a fait de ceux qui m'avaient ri d'arrêter de rire étaient quand, après plusieurs jours, il est devenu évident que plusieurs très difficiles à reproduire des bugs que quelques-uns de mes collègues recherchaient désespérément avaient disparu." (de chat )
"Problèmes"? P>
Si vous n'allez pas modifier la valeur d'un pointeur transcuté (il est utilisé uniquement pour une entrée passe-par-référence à une fonction), marquez-le est Les versions modernes de GCC ont pris en charge l'avertissement lorsque vous essayez de lancer une variable La seule chose à surveiller est exactement quel em> vous marquez const code>. Idem si la valeur d'une variable particulière ne changera pas après son initialisation. Si une fonction est sécuritaire d'appeler sur une instance de classe code> const code>, marquez-le
const code> aussi. Plus les articles sont correctement annotés
Const CODE>, moins vous êtes susceptible de faire une erreur par inadvertance et des optimisations du compilateur seront théoriquement capables de fonctionner en l'absence de connaissances complètes (telles que la compilation avec seulement Prototypes de fonction disponibles). P>
const code> à un non-
const code> un. Je vous suggère de laisser ces avertissements activés. P>
const code>;
Const Char * FOO () Code> n'est pas le même que
char * foo () const code>. p>
Je ne demande pas comment utiliser const. Je sais déjà comment utiliser const. Je cherchais problèmes i> avec const.
Le problème avec const est les programmeurs qui l'utilisent de manière incorrecte notre inconventionnement p>
Les deux principaux problèmes que j'ai connus de fréquents plaintes concernant les groupes de discussion, sont p>
La nécessité de perdre beaucoup de temps à soutenir les API de non-Conscons (en particulier de Microsoft). P> Li>
le doit définir la version constante et non constitue de une méthode . p> li> ul>
Je pense que ce dernier pourrait / devrait être soutenu par la langue. P>
éventuellement conjointement avec la prise en charge des implémentations de la fonction de membre de Covariant, car les deux nécessitent un moyen de récupérer le type de Un troisième numéro est que P>
acclamations et hth., p> Ceci code> Pointeur. P>
Quelles API Microsoft ne sont pas-Cons-Cons-ci? IIRC L'API Windows utilise LPCTSTRS, MFC utilise Const correctement IIRC, etc. Je ne peux penser à aucun.
@Rup: aurait besoin de beaucoup de recherches qui les traversent tous. Je rapporte ce que les gens se sont plaints, mais je peux confirmer une expérience propre. S'il n'y avait que quelques fonctions problématiques, je me souviendrais peut-être des noms, mais tout est fini.
@Rup: De nombreuses API Microsoft n'utilisent pas beaucoup de const. Quand était la dernière fois que vous avez vu une poignée constante? Ou un const iDirect3Ddevice9 *? Microsoft utilise Const pour les chaînes et c'est à ce sujet.
@Deadmg: A Poignée code> est un objet opaque que vous ne pouvez pas modifier de toute façon sans utiliser les fonctions de l'API. Pour les interfaces COM, ils utilisent des attributs tels que
[in] code> et
[out] code>. Et pour la plupart des autres types C, ils utilisent
const code>.
Peut-être que ce n'est pas purement win32 mais com btr code> ne peut pas être un
const code> (puisqu'il s'agit d'un
Typedef code> qui ne permet pas de mettre le
const code> sur la partie correcte du type).
@Philipp: Vous pouvez modifier le la poignée code> juste bien; Vous ne pouvez pas facilement modifier la chose que cela finit par pointer.
poignée code> étant
const code> aiderait à éviter les personnes d'oublier cela.
+1 pour "la nécessité de définir la version de const et non constitue d'une méthode". !
@LitB Ah j'ai raté que sur ma première lecture. +1 de moi aussi pour ça.
@Tomalak Notez que "@name" en informera l'utilisateur uniquement si remplacer (
@Johannesschab: Peut-être que je me cache: p (ok)
Que voulez-vous dire par const ne pas se propager à posséder des objets possédés? Si vous tenez une référence constante à une structure, tous les membres sont également considérés comme constants. Vous avez même le mot clé mutable code> pour permettre la mise en œuvre des caches (c'est-à-dire qu'il n'a pas d'impact sur la sortie si cette variable change).
@Pierrebdr: Je pense que ce qu'ils veulent dire, c'est qu'un membre int * code> est vu comme
int * cons code> (et pas
int const * code>) de l'intérieur une fonction membre de Const. En conséquence, ce qu'il pointe pour peut toujours être changé.
@Alf: Pouvez-vous ajouter des liens relatifs au "besoin d'ajouter les versions de const et non const"?
@Richard: C ++ FAQ A > B> est un bon point de départ. J'ai fait un peu de google et j'ai découvert que de nombreuses autres ressources sont obsolètes, y compris une gotw par Sutter d'herbes, liée à partir de La page Wikipedia sur la correction de const b>. Herb's Gotw B> conseille "lors de l'utilisation de la valeur de retour pour non -Builtine Types de retour, préférez renvoyer une valeur de const », raisonnable dans sa journée, mais avec laquelle avec Mojo ou C ++ 0x empêche« déménager »efficace.
Un problème est que la langue vous permet également de const_cast, ce qui défait le but d'utiliser Cons en premier lieu. P>
pas vraiment comme vous ne pouvez le jeter explicitement et vous devez évidemment être capable de const_cast pour soutenir les API hérités
Non plus ... const code> serait inutile sans b> la possibilité de la jeter, car dans le code du monde réel, vous devez traiter des APIS écrites par les programmeurs qui ne font pas ' T Comprendre la constance Constance (ou le retour dans une heure était
const code> ne faisait pas encore partie de C ++).
@Fredoverflow Je vois ... Je n'avais jamais rencontré cette situation auparavant. Merci pour la clarification.
@JK Le problème que j'ai rencontré est lorsque j'ai une fonction Const et un autre développeur Const_cast l'emporte, ce qui a vaincu l'intégralité du point de le faire en premier lieu. Au moins c'est mon souvenir.
@Fredoverflow: Mais peut-être que ce serait une bonne chose si ces programmeurs étaient chassés et tués par des personnes qui ne peuvent plus travailler autour de leur code brisé par la conscience? ;-) En ce qui concerne le code antique - Quelque chose peut toujours être un déficit de la langue même si la motivation du déficit est de soutenir le code pré-standard et / ou les conventions. Par exemple, vous pouvez penser que la conversion automatique sur VOID * code> est un déficit de C ++: il est nécessaire pour E.G.
std :: memcpy code>, mais dans le contexte de C ++, les fonctions ne doivent pas être conçues pour accepter silencieusement tout pointeur indépendamment de la sécurité de type.
@Dave: Pourquoi i> Le développeur a-t-il jeté-la. La plupart des cases sont diaboliques et / ou inutiles. Si vous ne faites pas confiance aux programmeurs, C ++ est la mauvaise langue.
@Fredoverflow Il était obligé de nécessiter un comportement particulier qu'il souhaitait, mais au détriment de tout le reste. Le changement n'a jamais fait passer, cependant. :)
@Steve: Comment les tuerait-il maintenant i> résoudre le problème? Laissez les fichus terminateurs faire le travail à fond et essuyer les non-croyants de l'histoire!
Non, bien que const_cast code> est légal, écrit à un objet-créé-
Const code> (même si vous avez éliminé la constance sur la variable i >) n'est pas légal.
(Cela dit, bien sûr, ce serait bien si const_cast code> n'a même pas existé. C'est un piratage et peut facilement conduire à l'illégalité que je décris ci-dessus.)
Qu'est-ce qui ne va pas avec Migration en C ++ à partir d'une langue qui n'a aucun concept Const est assez difficile, de nombreux échecs pour voir le point. P> Const code> est que de nombreux programmeurs ne semblent pas être capables de le comprendre complètement et qu'un projet "demi-constance" ne fonctionne tout simplement pas. C'est ce que vous devez savoir: p>
foo code> vs. code> const foo code> (ou
foo const code>) li>
foo & code> vs. code> const foo & code> (ou
foo const & code>)
foo * code> vs. code> const foo * code> (ou
foo const * code>)
foo * const code> et
const foo * const code> (ou
foo const * const code>) li>
ul> li>
void foo :: mutateur () code> vs. code> int foo :: accessor () const code>
itérateur code> vs. code> const_iterator code>
const itérateur code> et
const const_iterator (code> li>
ul> li>
ol>
NIT-Cueillette: Les références aux objets ne peuvent pas être constituées, mais les références peuvent faire référence à des objets constants. (La plupart des gens savent ce que vous voulez dire, mais la distinction est plus importante avec les pointeurs, où nous avons à la fois des indicateurs de const et des indications à Const.)
@Phil: Droite, j'ai changé les pièces pertinentes de l'anglais vers C ++ ;-)
Que de nombreux programmeurs ne comprennent pas que ce n'est pas un problème avec const code>. C'est un problème avec les programmeurs et l'état sérieusement pathétique d'éducation de programmation dans le monde occidental.
@Chris: Merci d'avoir attrapé ça!
La question ne demande pas comment utiliser const. Je sais déjà comment utiliser const. La question concerne les inconvénients de la const.
Bonne dégagement des utilisations de Cons Fred, mais où puis-je trouver une bonne référence sur les cas d'utilisation donnés? Je suis nouveau à l'idée que const peut économiser beaucoup de bugs, mais j'ai besoin d'une compréhension approfondie de celle-ci avant utilisation. J'espère que quelqu'un peut aider avec un bon tutoriel / liens
@Overtheedge Je vous suggère d'acheter "efficace C ++" (3ème édition) de Scott Meyers. L'élément 3 consacre 10 pages au sujet.
Le problème principal est que vous devez l'écrire. Il devrait être la valeur par défaut, et toutes les variables ou paramètres mutables doivent être spécifiés explicitement. P>
Ne peut pas uplifier cela assez. Même si (ou parce que), cela ferait des ravages avec la plupart des idées préconçues des programmeurs.
Sauf pour deux choses: la majorité des variables sont créées pour être écrites. Les avoir tous en lecture seule par défaut crée plus de travail. De plus, la philosophie de la langue C et C ++ est que le programmeur sait ce qu'ils font et que la langue ne devrait pas vous empêcher de faire ce que vous voulez.
@Jay "La majorité des variables sont créées pour être écrites." - une fois i>. Je modifie rarement la valeur d'une variable après sa première affectation (les conteneurs sont une sorte d'exception).
Vous n'allez jamais trouver que l'une ou l'autre est meilleure. Certains objets que vous créez pour la lecture / écriture (comptoirs en boucle, itérateurs, conteneurs, flux, la plupart des chaînes) et d'autres que vous ne vous attribuez à une fois - en fait, je ne peux penser à aucun exemples pour celui-ci. Pourquoi votre ponctuel écrit-t-il des initialisations non constantes?
Wow, j'ai totalement manqué votre réponse lorsque j'ai écrit le mien (maintenant supprimé, disait la même chose). Une des raisons que j'ai supprimées le mien est que je ne peux pas imaginer que c'est une valeur irrégulière pour les variables locales. Mais je peux définitivement imaginer qu'il est sain d'esprit de paramètres de valeur. Donc, peut-être faire des paramètres const par défaut, sauf si vous mettez le mot clé "mutable"?
De nombreuses variables de membre de classe sont initialisées uniquement dans le constructeur, puis ne changent jamais de la durée de vie de la classe. J'ai parfois changé ma politique pour rendre ces const et public, plutôt que non-consistant, privé avec des getters publics. Je sais que beaucoup de gens n'aiment pas le concept de membres publics et, s'ils sont non-consons, je suis d'accord, mais si elles sont je ne vois pas la question.
@JOH: J'ai généralement const code> variables locales aussi. Bien sûr, la question est beaucoup plus petite: cela n'aide pas en ce qui concerne la constance, mais contribue à la recherche d'erreurs.
@Philipp: Phew, je suis content que je ne sois pas le seul à faire des variables locales const code>.
:) code>
-1 De moi j'ai peur. Comme le suggère qu'il s'agisse d'une défaillance raisonnable pour les paramètres de fonction, mais il est rare que je reçoive une variable locale dont la valeur reste fixée après son attribution initiale. C ++ est une langue impérative; Il n'y a pas de honte à l'attribution de deux fois :)
@J_RANDOM: C ++ est une langue multi-paradigme et, par exemple, prend en charge de plus en plus la programmation fonctionnelle. Je me trouve sur des données mutables de moins en moins au fil des ans et de faire tout ce que const code> par défaut.
Une chose qui est « mauvais » est que vous ne pouvez pas convertir T ** à T const * const * qui devrait être autorisé car il est dangereux. Ne pas permettre à T ** pour convertir en T const ** est correct, que la conversion n'est pas valide. P>
Je l'ai parfois mentionné que const est en fait un moyen pas cher de « diviser » l'interface sur les méthodes et les méthodes d'écriture en lecture seule. Il serait probablement peu pratique en C ++. Il serait plus pratique en Java pour avoir des versions ReadOnly des collections cependant, où ils ne sont pas const et où leurs types de collections sont plus orientées objet. P>
constness ne se propage pas: La question ici est que si je Pimpl ma classe, la constness n'est pas « vérifié » par le compilateur, à savoir ma classe d'interface peut avoir un appel de méthode « const » une méthode non-const sur le Pimpl et le compilateur ne se plaindront pas. C'est parce que la seule chose que ma méthode const est garanti de ne pas faire est de changer le pointeur pour pointer vers un objet différent, et mon Pimpl ne va jamais changer. Il pourrait même être un pointeur const (pas de pointeur sur const). P>
L'absence de co-variance appropriée entre shared_ptr
shared_ptr
const shared_ptr
"Impossible de convertir t ** t ** code> sur
t const * const * code>" - Cette partie est fausse (au moins avec les compilateurs que j'utilise); Je me souviens que c'était une gêne dans C mais C ++ a eu raison.
Vous pouvez avoir une vérification constante de la classe PIMPL, pas de gros problème ... Par exemple, regardez l'utilisation QTS des classes PIMPL .. (Ils utilisent 2 fonctions privées PIMPL-Accessor (Const / NonConst) pour accéder à l'objet PIMPL, si vous le souhaitez. Pour vous assurer que vous n'accédez pas à l'objet PIMPL sans utiliser ces fonctions (et de contourner ainsi la Const-Check), vous pouvez utiliser un video entièrement opaque code> Void * code> pour l'objet PIMPL et ajouter des réinterpret_casts à l'acesseur. Fonctions (examinez l'implémentation de IE Q_Declare_private)
@Anatolyg: Vous êtes correct. Le premier paragraphe ne décrit pas quelque chose de "faux" avec const code> car ce n'est pas vrai. Voir 4.4 [Conv.Qual] / 4 de ISO / CEI 14882: 2003.
Une chose est que cela reste possible le subvert. C'est-à-dire qu'il est toujours légal de faire quelque chose comme ceci: Vous pouvez même utiliser des éléments tels que Il s'agit d'un compromis entre le compilateur appliquant Ce qui conduit à une autre limitation, en ce sens qu'il n'a pas été universellement adopté, ce qui est en partie dû à un autre problème, ce qui consiste à utiliser Memset code> pour l'interversion sans un
const_cast code> . P>
const code> et permettant une certaine flexibilité pour les interfaces de conscons code> const p> p>
const code> est une proposition tout-ou-rien. Si vous commencez à l'utiliser, vous devrez le propager tout au long de votre base de code. P> p>
Non, c'est peut-être un comportement non défini (si l'objet d'origine a été créé const code>) et dans le contexte de cette fonction doit être supposé être. Un
const_cast code> est légal, mais écrit à un objet créé comme
const code>, que vous ayez déposé la constance ou non, est illégal.
Eh bien, oui, mais si vous pensez être constitué d'un contrat ou d'une promesse que je ne le changerai pas (même s'il s'agissait de non-cons autres auparavant), il est possible de le casser.
Mais vous pouvez faire des promesses sous forme de commentaires dans chaque langue, puis les subverver. const code> est un outil non-commentaire / intégré qui vous oblige à ne pas casser le contrat par défaut i>, alors que dans les langages non-constants, vous pouvez changer accidentellement quelque chose de documenté invariant.
Un autre problème qui n'a pas encore été mentionné est la possibilité d'une interface mal conçue pour subverver const (même en l'absence de moulages).
Exemple: P>
class TreeNode { public: TreeNode& getParent() const { return *parent_; } TreeNode& getLeft() const { return *left_; } TreeNode& getRight() const { return *right_; } private: //TreeNode has a pointer to the Tree to enable navigation of the tree. //Assume that other design constraints mean that this must be a pointer //rather than a reference. TreeNode* parent_; TreeNode* left_; TreeNode* right_; }; //This function demonstrates the ability for const to be subverted. TreeNode& remove_const(TreeNode const& toRemoveConstFrom) { TreeNode& parent(toRemoveConstFrom.getParent()); TreeNode& leftChild(parent.getLeft()); TreeNode& rightChild(parent.getRight()); return &toRemoveConstFrom == &leftChild ? leftChild : rightChild; }
La plupart des réponses ci-dessous des choses d'état tels que "Qu'est-ce qui ne va pas avec const code> est que X Les gens font Y". Ce ne sont pas des réponses mais symptômes em>. Ce ne sont pas un problème avec
const code>. Il y a à peine em> toute mauvaise chose avec
const code> ... Ce sont des choses mal avec des personnes qui ne peuvent pas ronger strong>. p>
Pourtant, il y a deux problèmes que j'ai eu avec Il n'y a aucun moyen de marquer une variable comme Il n'y a aucun moyen de spécifier qu'un objet adopté par référence à une fonction ne changera pas pendant la durée de l'appel de la fonction. const code> est génial.
const code> est important.
const code> -Correcness est nécessaire conditionner pour qu'une API soit bonne. p>
const code>, à plusieurs reprises. P>
const code> rétroactivement. Vous devez soit déclarer un code variable, auquel cas vous avez em> pour l'initialiser immédiatement. Et si le code d'initialisation contient un
si code>, cependant? Vous avez le choix d'omettre l'omission du
const code> (indésirablement), à l'aide de l'opérateur
? Code> au lieu de
si code> (nuit à la lisibilité). Java obtient ce droit, BTW -
const code> Les variables ne doivent pas être initialisées tout de suite, ils doivent simplement être initialisés avant em> ils sont d'abord lus, et ils doivent être initialisé dans tous les succursales em> d'un
si code>. p> li>
const t & t code> ne signifie pas em> signifie que l'objet pointé par
t code> ne changera pas, mais seulement que la référence
t code> ne peut pas être utilisé pour le changer. Le compiller doit toujours supposer que tout appel de fonction qu'elle ne voit pas dans pourrait em> changer l'objet. Certains cas empêchent de nombreuses optimisations. P> Li>
ul>
Je pense qu'ils sont utiles car rendent le code plus facile à comprendre.
Besoin d'indiquer une question avant que vous obtiendrez votre réponse,
Le seul problème que je vois avec
const code> est que son état de préparation et Effets i> varie considérablement en fonction du niveau du programmeur C ++ (une certaine confusion sur quel élément
const < / code> s'applique dans une déclaration complexe, par exemple). En plus de cela fait partie de la langue et doit être utilisé - tant que le livre de B.Stroustrup a été lu :-)
@Vilx Ne pensez-vous pas que "alors que (x
Intéressant de voir combien de fois cette question est fermée et rouvert.
@David: On dirait une question pour moi.
voté pour rouvrir. Question utile définitivement. Dommage que nous ne puissions pas y arriver à la communauté wiki. Ce n'est certainement pas une question non-CW. IIRC, une règle de base est la suivante: si par nature, il ne peut pas avoir une "réponse acceptée", elle devrait être cw.
@Tomalak C'est plus une question maintenant que cela a été édité!
@David: Je ne vois aucune modification. Peut-être que c'était trop rapide.
@Tomalak: Il a été édité une trentaine secondes après avoir été mise en place. Je trouve franchement la réponse à cette question hilarante, car il y a une question exactement identique à propos de ADL que personne ne veut voter pour fermer.
@Deadmg Je ne comprends pas le vote à proximité non plus.