Lorsque je lis des tutoriels et du code écrit en C++, je tombe souvent sur le mot clé const
.
Je vois qu'il s'utilise comme suit:
const int x = 5;
Je sais que cela signifie que x
est une variable constante et probablement stockée dans une mémoire en lecture seule.
Mais quels sont
void myfunc( const char x );
et
int myfunc( ) const;
?
void myfunc(const char x);
Cela signifie que le paramètre x
est un caractère dont la valeur ne peut pas être modifiée dans la fonction. Par exemple:
void myfunc(const char x)
{
char y = x; // OK
x = y; // failure - x is `const`
}
Pour le dernier:
int myfunc() const;
Ceci est illégal sauf si cela se trouve dans une déclaration de classe - les fonctions membres const
empêchent la modification de tout membre de la classe - les fonctions const
non membres ne peuvent pas être utilisées. dans ce cas, la définition serait quelque chose comme:
int myclass::myfunc() const
{
// do stuff that leaves members unchanged
}
Si vous avez des membres de classe spécifiques devant être modifiables dans les fonctions membres const
, vous pouvez les déclarer mutable
. Un exemple serait un membre lock_guard
qui rend les fonctions membres de la variable const
et non -const
threadsafe, mais doit changer au cours de sa propre opération interne.
Le premier exemple de fonction est plus ou moins dénué de sens. Plus intéressant serait:
void myfunc( const char *x );
Cela indique au compilateur que le contenu de *x
ne sera pas modifié. Autrement dit, dans myfunc()
, vous ne pouvez pas faire quelque chose comme:
strcpy(x, "foo");
Le deuxième exemple, sur une fonction membre C++, signifie que le contenu de l'objet ne sera pas modifié par l'appel.
Donc, étant donné:
class {
int x;
void myfunc() const;
}
someobj.myfunc()
n'est pas autorisé à modifier quoi que ce soit comme:
x = 3;
Ce:
void myfunc( const char x );
signifie que vous ne pouvez pas changer x
dans la fonction, c'est-à-dire que c'est illégal:
void myfunc( const char x ) {
x = ...;
}
tandis que:
int myfunc() const;
n'a de sens que si myfunc () est une méthode dans une classe; cela signifie fondamentalement que la méthode ne peut pas modifier l'instance de la classe (c'est-à-dire que l'état de l'instance avant et après l'appel de instance.myfunc () sera le même).
Avant un identifiant de variable, const
indique que la variable peut être initialisée puis non modifiée.
Après un nom de méthode de classe, const
indique que la méthode ne modifiera pas l'état observable de la classe. Le mot clé mutable
permet de modifier des données internes.
Avant un pointeur ou une variable de référence, const
indique que l'identificateur ne sera pas utilisé pour modifier les données référencées, bien qu'elles puissent être modifiées par d'autres moyens.
const int *pInt = &x;
Const peut également être utilisé pour indiquer que le pointeur lui-même ne peut pas être modifié:
int * const pInt = &x;
J'ai trouvé une très bonne explication sur: http://duramecho.com/ComputerInformation/WhyHowCppConst.html
Fondamentalement, toute confusion réside dans les différents cas d'utilisation du mot clé const
. Selon l'endroit où vous placez const
, vous indiquez que quelque chose doit être immuable ou que quelque chose ne doit pas pouvoir changer autre chose. 'quelque chose' peut être une variable ou un pointeur ou une fonction/méthode, ce que vous ne voulez pas qu'il puisse changer la valeur des variables transmises aux fonctions ou aux variables membres de l'objet.
Le qualificatif const
signifie qu'une variable/pointeur défini par const
ne peut pas être modifié par votre programme et qu'il recevra sa valeur soit par une initialisation explicite, soit par un moyen dépendant du matériel.
Un pointeur défini comme const
dans les déclarations de paramètre, le code de la fonction ne modifiera pas ce sur quoi il pointe. Fondamentalement, vous pouvez utiliser le pointeur qui fonctionne quasiment en "lecture seule".
Par exemple:-
void foo(const char *x)
{
while(*x)
{
if(*x==' ') cout << '-'; //printing - when a space is encountered
else cout << *x;
x++;
}
}
La fonction ci-dessus est correcte et ne montrera aucune erreur. Mais si foo avait quelque chose qui pourrait changer la chaîne passée. dire une fonction qui remplace les espaces par $. N'imprimez pas $ mais changez-le en $. Quelque chose comme ça:-
void foo(const char *x)
{
while(*x)
{
if(*x==' ') *x = '$'; //printing - when a space is encountered
else cout << *x;
x++;
}
}
alors il ne compilerait pas c.-à-d. une erreur d’attribution à un emplacement de mémoire en lecture seule.
La différence entre les deux réside dans le fait que le premier a le type void(char)
et le second le type int()const
.
Une fonction ayant un tel type avec const
à la fin ne peut être qu'une fonction membre d'une classe et cela signifie que la fonction membre ne modifie pas la valeur de la classe (à laquelle this
se réfère) vue de l'extérieur de la classe. Le compilateur va vérifier cela dans une certaine mesure, et toute écriture directe dans un membre de classe dans une fonction membre const entraîne une erreur de compilation, et la fonction ne peut directement appeler que des fonctions membres const (des directives spéciales existent pour que Un compilateur écrit par un membre ne changera pas la valeur de la classe vue de l’extérieur (ceci est fait avec le mot clé mutable
).
Dans les fonctions que vous avez présentées, il y avait un paramètre de type char const
. Un tel paramètre ne peut pas être modifié dans sa fonction. Cela n'a cependant aucun effet sur le type de la fonction, ni sur les appelants de la fonction.
void myfunc(const char x)
est très similaire à const int x = 5
dans votre exemple: Il déclare une constante disponible localement dans la fonction myfunc
. Comme c'est une constante, sa valeur ne peut pas être changée.
int myfunc() const
est une fonction membre d'une classe. const
indique que la fonction ne changerait pas l'instance de la classe sur laquelle la fonction est exécutée. Ainsi, dans la fonction, vous ne pouvez pas faire quelque chose comme this->foo = 7
ou appeler une autre fonction qui ne soit pas const.