Que signifie exactement le mot clé const
en C++ lorsqu'il est écrit à la fin d'une fonction membre (après la liste d'arguments)?
Cela signifie que *this
est const
à l'intérieur de cette fonction membre, c'est-à-dire qu'elle ne modifie pas l'objet.
Le mot clé
this
est une expression de valeur dont la valeur est l'adresse de l'objet pour lequel la fonction est appelée. Le type dethis
dans une fonction membre d'une classeX
estX*
. Si la fonction membre est déclaréeconst
, le type dethis
estconst X*
. [section 9.3.2 §1]Dans une fonction membre
const
, l'objet pour lequel la fonction est appelée est accessible via un chemin d'accèsconst
; par conséquent, une fonction membreconst
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 nonconst
ne peut pas être appelée [1]un objet const
, car il pourrait potentiellement essayer de le modifier.
[1] Remarque: un temporaire n'est pas un objet const
sauf s'il est de type const
.
const
à la fin d'une signature de fonction signifie que la fonction doit supposer que l'objet dont elle est membre est const
. Concrètement, cela signifie que vous demandez au compilateur de vérifier que la fonction membre ne modifie en rien les données d'objet. Cela signifie demander au compilateur de vérifier qu'il ne modifie pas directement les données des membres et qu'il n'appelle aucune fonction qui ne garantit pas elle-même qu'elle ne changera 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 de membre et que vous n'appelez aucune fonction qui ne garantit pas qu'il ne changera pas l'objet.
Tout cela fait partie de la philosophie const correctness. Essentiellement, cela signifie que si les choses fonctionnent en ce moment et qu'elles ne changent pas, elles ne se briseront jamais. En d'autres termes, il est plus facile de travailler avec des choses constantes de manière fiable. Ce const
à la fin des signatures de fonction est un outil pour vous empêcher d'interrompre les choses. Cela signifie que vous devez mettre const
partout où vous le pouvez.
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. Cela est utile par exemple lorsque vous avez une classe qui encapsule son propre lock_guard, qui doit changer sa valeur pour appliquer la sécurité des threads même dans les fonctions membres const
.