88 votes

Quelle est la signification d'une const à la fin d'une fonction membre ?

Que signifie exactement le mot-clé const en C++ lorsqu'il est écrit à la fin d'une fonction membre (après la liste des arguments) ?

99voto

Oli Charlesworth Points 148744

Cela signifie que *this est const à l'intérieur de cette fonction membre, c'est-à-dire qu'il ne modifie pas l'objet.

Le mot-clé this est une expression de type prvalue dont la valeur est l'adresse de l'objet pour lequel la fonction est appelée. Le type de this dans une fonction membre d'une classe X est X*. Si la fonction membre est déclarée const, le type de this est const X*. [section 9.3.2 §1]

Dans une fonction membre const, l'objet pour lequel la fonction est appelée est accédé via un chemin d'accès const; par conséquent, une méthode membre const ne doit pas modifier l'objet et ses membres de données non statiques. [section 9.3.2 §2]

Cela signifie qu'une fonction membre const peut être appelée sur une instance const de la classe. Une fonction membre non-const ne peut pas être appelée sur [1] un objet const, car elle pourrait potentiellement essayer de le modifier.

[1] Note : un objet temporaire n'est pas un objet const à moins qu'il ne soit de type const.

0 votes

Ah d'accord merci! et comment puis-je accéder à l'intérieur d'une fonction constante un pointeur vers une variable membre? si j'essaie int* ptr = &m_value je reçois une erreur C2440 const int * ne peut pas être converti en int *

0 votes

Et est-ce que cela aide le compilateur à optimiser le code assembleur ou quel est exactement le bénéfice?

2 votes

@Mat: déclarez votre variable comme constante aussi: const int* ptr = &m_value

41voto

wilhelmtell Points 25504

const à la fin d'une signature de fonction signifie que la fonction doit supposer que l'objet dont elle est membre est const. En termes pratiques, cela signifie que vous demandez au compilateur de vérifier que la fonction membre ne modifie pas les données de l'objet de quelque manière que ce soit. Cela signifie demander au compilateur de vérifier qu'il ne modifie pas directement les données membres et qu'il n'appelle pas de fonction qui ne garantit pas qu'elle ne modifiera pas l'objet.

Lorsque vous créez un objet const, vous demandez au compilateur de s'assurer que cet objet ne change pas au-delà de son initialisation. Cela signifie à son tour que le compilateur vérifiera que vous ne modifiez pas directement ses données membres et que vous n'appelez aucune fonction qui ne garantit pas qu'elle ne modifie pas l'objet.

Tout cela fait partie de la philosophie de la const-correctness. Essentiellement, cela signifie que si les choses fonctionnent maintenant et ne changent pas, elles ne se casseront jamais. En d'autres termes, les choses constantes sont plus faciles à manipuler de manière fiable. Ce const à la fin des signatures de fonction est un outil pour vous interdire de tout casser. Cela signifie donc que vous devriez mettre const partout où c'est possible.

0 votes

Merci pour cette explication. Y a-t-il des arguments contre l'utilisation de const dans une fonction qui ne change pas l'objet ? J'ai l'impression que le logiciel pourrait devenir moins maintenable de manière flexible si vous décidez soudainement, par exemple, de modifier une conception et que vous avez besoin d'appeler une fonction non const dans une fonction actuellement déclarée comme const, puis peut-être qu'une grande chaîne de fonctions appelant cette fonction doit aussi être modifiée.

1 votes

Non, il n'y a aucun argument contre l'utilisation d'une const. C'est-à-dire, à moins que vous ne sachiez dès maintenant, au moment de concevoir votre classe, qu'une fonction membre doit être autorisée à modifier l'objet. C'est une question de conception que vous devriez vous poser tôt, et cela devrait être facile à répondre. Il ne s'agit pas de "laisser la porte ouverte pour plus tard". Plutôt, il s'agit de savoir si la fonction doit modifier l'objet ou ne doit pas le modifier. C'est une question de oui ou non, noir ou blanc, sans nuances, et cela devrait être facile à répondre. Remarque : ce n'est pas une question de peut-elle modifier l'objet, mais doit-elle le faire.

1 votes

Cela signifie à son tour que la philosophie de la const-correctness vous force dès le début à être très conscient de ce que chaque fonction fait. Cela vous oblige à décider et à être très clair sur la raison d'être de chacune des fonctions membres. C'est une bonne chose. Ce que vous demandez, c'est de laisser une porte ouverte pour changer la raison d'être d'une fonction, et c'est une mauvaise chose. Vous ne devriez changer comment une fonction fait ce qu'elle est censée faire, pas ce qu'elle fait. Pensez aux utilisateurs de votre API (qui pourraient être vous-même). Ne tirez pas le tapis de sous leurs pieds!

12voto

Steve Townsend Points 36948

Les optimisations du compilateur sont possibles, mais le principal avantage est d'appliquer le contrat exprimé dans la déclaration de la fonction - si vous définissez une fonction membre comme const, le compilateur empêche toute modification de l'objet à l'intérieur de cette fonction.

Vous pouvez exempter des champs individuels de la classe de cette restriction en utilisant mutable dans leur déclaration. C'est utile par exemple lorsque vous avez une classe qui encapsule son propre lock_guard, qui doit changer sa valeur pour assurer la sécurité du thread même à l'intérieur des fonctions membres const.

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