40 votes

Pourquoi la const-correctness est-elle spécifique au C ++?

Avertissement: je suis conscient qu'il y a deux questions sur l'utilité de la const-correctness, cependant, aucun discuté de la façon dont const-correct est nécessaire en C++, contrairement à d'autres langages de programmation. Aussi, je ne suis pas satisfait des réponses fournies à ces questions.

J'ai utilisé un peu de langages de programmation aujourd'hui, et la chose qui me dérange en C++, c'est la notion de const-correct. Il n'y a pas de notion en Java, C#, Python, Ruby, Visual Basic, etc., cela semble être très spécifique au C++.

Avant de me référer à la C++ FAQ Lite, je l'ai lu, et il ne me convainc pas. Parfaitement valides, fiables les programmes sont écrits en Python tout le temps, et il n'y a pas de mot-clé const ou l'équivalent. En Java et en C#, les objets peuvent être déclarées final (ou const), mais il n'y a pas const fonctions de membre ou const paramètres de la fonction. Si une fonction n'a pas besoin de modifier un objet, il peut prendre une interface qui fournit uniquement un accès en lecture à l'objet. Cette technique peut également être utilisé en C++. Sur les deux monde réel C++ systèmes que j'ai travaillé, il y avait très peu d'utilisation de const n'importe où, et tout a bien fonctionné. Donc, je suis loin d'être vendus sur l'utilité de laisser const contaminer une base de code.

Je me demande ce que c'est en C++, qui rend const nécessaire, contrairement à d'autres langages de programmation.

Jusqu'à présent, j'ai vu qu'un seul cas où const doit être utilisé:

#include <iostream>

struct Vector2 {
    int X;
    int Y;
};

void display(/* const */ Vector2& vect) {
    std::cout << vect.X << " " << vect.Y << std::endl;
}

int main() {
    display(Vector2());
}

La compilation de ce avec const commenté est accepté par Visual Studio, mais avec avertissement C4239, la non-extension standard utilisé. Donc, si vous voulez la syntaxiques brièveté du passage dans temporaires, en évitant les copies, et de rester conforme à la norme, vous devez passer par référence const, pas moyen de contourner cela. Encore, c'est plus un caprice qu'une raison fondamentale.

Sinon, il n'y a vraiment pas de situation où const doit être utilisé, sauf lors de l'interfaçage avec d'autres code qui utilise const. Const me semble, à peu de chose qu'un moralisateur, la peste qui se propage à tout ce qu'il touche :

La raison qui const fonctionne en C++ est parce que vous pouvez le jeter au loin. Si vous ne pouvais pas le jeter loin, alors votre monde serait sucer. Si vous déclarez une méthode qui prend un const Bla, vous pourriez passer une non-const Bla. Mais si c'est le inverse, vous ne pouvez pas. Si vous déclarer une méthode qui prend un non-const Bla, vous ne pouvez pas passer à un const Bla. Alors maintenant, vous êtes coincé. Si vous progressivement besoin d'une version de const tout ce qui n'est pas const, et vous jusqu'à la fin avec un monde de l'ombre. En C++, vous sortir avec elle, parce que, comme avec rien en C++ c'est purement facultatif si vous voulez vérifier ou non. Vous pouvez simplement frapper la constness loin si vous ne l'aimez pas.

Anders Hejlsberg (C# architecte), CLR Choix de Conception

63voto

Michael Ekstrand Points 12849

Const exactitude offre deux avantages notables pour le C++ qui est je pense, l'un de ce qui le rend assez unique.

  • Il permet omniprésente notions de mutables/données immuables, sans exiger un tas d'interfaces. Différentes méthodes peuvent être annotées quant à savoir si ou non ils peuvent être exécutées sur les objets const, et le compilateur impose cette. Oui, il peut être pénible parfois, mais si vous l'utilisez régulièrement et de ne pas utiliser const_cast vous avez compilateur-vérification de la sécurité en ce qui concerne mutable vs des données immuables.
  • Si un objet ou d'un élément de données est - const, le compilateur est libre de le placer dans la mémoire en lecture seule. Cela peut particulièrement question dans les systèmes embarqués. C++ prend en charge ce; de quelques autres langues. Cela signifie également que, dans le cas général, vous ne pouvez pas vous en toute sécurité cast const loin, bien que dans la pratique, vous pouvez le faire dans la plupart des environnements.

C++ n'est pas la seule langue avec const exactitude ou quelque chose comme ça. OCaml et de Standard ML ont un concept similaire, avec une terminologie différente — presque toutes les données sont immuables (const), et quand vous voulez quelque chose à être mutable vous utilisez un autre type (un ref type) pour accomplir cette. Il est donc tout à fait unique de C++ à l'intérieur de ses langues voisines.

Enfin, venant de l'autre sens: il y a eu des fois où j'ai envie const en Java. final parfois ne pas aller assez loin plus loin en créant simplement des données immuables (surtout immuable vues de données mutable), et ne veulent pas créer des interfaces. Regardez les Inmodifiable de soutien à la collecte dans l'API Java et le fait qu'il vérifie uniquement au moment de l'exécution si la modification est autorisée pour un exemple de pourquoi const est utile (ou au moins l'interface devrait être la structure de l'agence deepend pour avoir la Liste et MutableList) — il n'y a pas de raison que d'essayer de muter immuable de la structure ne peut pas être une compilation type d'erreur.

30voto

Nemanja Trifunovic Points 17239

Je ne pense pas que quiconque prétende que la constance est "nécessaire". Mais encore une fois, les cours ne sont pas vraiment nécessaires non plus, n'est-ce pas? Il en va de même pour les espaces de noms, les exceptions, ... vous obtenez l'image.

La correction de const permet de détecter les erreurs au moment de la compilation, et c'est pourquoi elle est utile.

16voto

Lou Franco Points 48823

const est un moyen pour vous d'exprimer quelque chose. Il serait utile dans n'importe quelle langue, si vous pensiez qu'il était important de l'exprimer. Ils n'ont pas cette fonctionnalité, car les concepteurs de langage ne les ont pas trouvés utiles. Si la fonctionnalité était là, elle serait à peu près aussi utile, je pense.

Je pense en quelque sorte aux spécifications de lancer en Java. Si vous les aimez, vous les aimeriez probablement dans d'autres langues. Mais les concepteurs des autres langues ne pensaient pas que c'était si important.

13voto

Jeremy Friesner Points 16684

Vous avez raison, const-correctness n'est pas nécessaire. Vous pouvez certainement écrire tout le code sans le mot clé const et obtenir des choses à travailler, comme vous le faites en Java et Python.

Mais si vous le faites, vous n'aurez plus le compilateur d'aide à la vérification de const violations. Les erreurs que le compilateur aurait parlé au moment de la compilation va maintenant être trouvés seulement au moment de l'exécution, le cas échéant, et donc prendre plus de temps pour diagnostiquer et résoudre le problème.

Donc, en essayant de renverser ou d'éviter la const-correctness fonction est simplement de rendre les choses plus difficile pour vous dans le long terme.

8voto

La programmation est écrit dans une langue qui sera en fin de compte traitées par l'ordinateur, mais qui est à la fois un moyen de communiquer avec l'ordinateur et d'autres programmeurs dans le même projet. Lorsque vous utilisez une langue, vous êtes limité aux concepts qui peuvent être exprimées en elle, et const est juste un concept, vous pouvez les utiliser pour décrire votre problème, et votre solution.

Constantness vous permet de vous exprimer clairement à partir de la conception, le code d'un concept que d'autres langues de l'absence. Comme vous venez à partir d'une langue qui ne l'a pas, il peut sembler que vous intrigué par un concept que vous n'avez jamais utilisé-si vous n'avez jamais utilisé avant, quelle importance cela peut-il être?

Le langage et la pensée sont étroitement couplés. Vous ne pouvez exprimer vos pensées dans la langue que vous parlez, mais la langue modifie également la façon dont vous pensez. Le fait que vous n'avez pas le mot-clé const dans les langues que vous avez travaillé avec implique que vous avez déjà trouvé d'autres solutions pour les mêmes problèmes, et ces solutions sont ce qui semble naturel pour vous.

Dans la question que vous dire que vous pouvez offrir une mutation de l'interface qui peut être utilisée par les fonctions qui n'ont pas besoin de modifier le contenu des objets. Si vous pensez à ce sujet pendant une seconde, cette même phrase est de vous dire pourquoi const est un concept que vous souhaitez travailler. Avoir à définir un non-mutation de l'interface et de la mettre en œuvre dans votre classe est un travail autour du fait que vous ne pouvez pas exprimer ce concept dans votre langue.

Constantness vous permet d'exprimer ces concepts dans une langue que le compilateur (et d'autres programmeurs) peut comprendre. Vous êtes l'établissement d'un compromis sur ce que vous allez faire avec les paramètres que vous recevez, les références du magasin, ou de la détermination des limites sur ce que les utilisateurs de votre classe sont autorisés à faire avec les références que vous fournissez. Joli beaucoup chaque non-trivial classe peut avoir un etat représenté par des attributs, et dans de nombreux cas, il existe des invariants qui doivent être conservées. Le langage permet de définir des fonctions qui offrent l'accès à des données internes tandis que dans le même temps, les limites de l'accès à un affichage en lecture seule qui ne garantit pas de code externe va briser votre invariants.

C'est le concept je m'ennuie de plus en cas de déménagement dans d'autres langues. Envisager un scénario où vous avez une classe C qui a, entre autres, un attribut a de type A doit être visible à un code externe (les utilisateurs de votre classe doit être en mesure de rechercher des informations sur une). Si le type de a tout la mutation de l'opération, puis de garder le code de l'utilisateur de la modification de votre état interne, vous devez créer une copie de l'un et de le retourner. Le programmeur de la classe doit être conscient qu'une copie doit être effectuée et doit effectuer (éventuellement cher) copie. D'autre part, si vous pouviez exprimer constantness dans la langue, vous pouvez simplement retourner une constante référence à l'objet (en fait une référence à une constante de la vue de l'objet) et il suffit de retourner l'élément interne. Cela permettra à l'utilisateur de code pour appeler une méthode de l'objet qui est vérifié que la non-mutation, préservant ainsi votre classe d'invariants.

Le problème (ou l'avantage, tout dépend du point de vue de constantness est qu'elle est d'origine virale. Lorsque vous offrent une constante référence à un objet, seules les méthodes signalé comme non-mutation peut être appelé, et vous devez indiquer au compilateur dont les méthodes ont cette propriété. Lorsque vous déclarez une méthode constante, on dit au compilateur que le code de l'utilisateur qui appelle cette méthode permettra de garder l'état de l'objet. Lorsque vous définissez (mettre en œuvre) une méthode qui a une constante de la signature, le compilateur va vous rappeler votre promesse et ont réellement besoin que vous n'avez pas en interne de modifier le données.

Le langage permet de dire au compilateur que les propriétés de vos méthodes que vous ne pouvez pas exprimer toute autre manière, et dans le même temps, le compilateur va vous dire quand vous n'êtes pas conforme à votre conception et d'essayer de modifier les données.

Dans ce contexte, const_cast<> ne doit jamais être utilisé, comme les résultats peuvent vous emmener dans le royaume de comportement indéfini (à la fois à partir d'une langue de point de vue: l'objet dans la mémoire en lecture seule, et à partir d'un programme point de vue: vous pourriez peut-être la violation des invariants dans d'autres classes). Mais qui, bien sûr, vous savez déjà si vous lisez le C++FAQ lite.

Comme une note côté, le mot-clé final en Java a vraiment rien à faire avec le mot-clé const en C++ lorsque vous traitez avec des références (en C++ références ou des pointeurs). Le mot-clé final modifie la variable locale à laquelle il se réfère, que ce soit un type de base ou de référence, mais n'est pas un modificateur de la visée de l'objet. Qui est, vous pouvez appeler la mutation des méthodes par le biais d'un renvoi définitif et de fournir ainsi des changements dans l'état de l'objet visé. En C++, les références sont toujours constante (vous ne pouvez les lier à un objet/variable au cours de la construction) et le mot-clé const modifie la façon dont le code de l'utilisateur peut faire face à la visée de l'objet. (Dans le cas des pointeurs, vous pouvez utiliser le mot-clé const à la fois pour la référence et le pointeur: X const * const déclare un pointeur constant sur une constante X)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X