const est l'abréviation de constante, signifiant à l'origine immuable et difficile à changer. En C++, il est utilisé pour modifier des variables de type intégré, des objets personnalisés, des fonctions membres, des valeurs de retour et des paramètres de fonction.

C++ const permet de spécifier une contrainte sémantique que le compilateur applique, permettant au programmeur d'indiquer au compilateur qu'une valeur reste inchangée. S'il existe effectivement une valeur qui reste inchangée pendant la programmation, vous devez utiliser explicitement const, afin de pouvoir obtenir l'aide du compilateur.

1. const modifie les variables de types ordinaires

const int  a = 7; 
int  b = a; // 正确
a = 8;       // 错误,不能改变

a est défini comme une constante, et a peut être affecté à b, mais a ne peut pas être affecté à nouveau. Affecter à une constante est illégal, car a est considéré comme une constante par le compilateur et sa valeur n'est pas autorisée à être modifiée.

Voyons maintenant les opérations suivantes :

Exemple

#include<iostream> using namespace std; int main(void) { const int a = 7; int *p = (int*)&a; *p = 8; cout<<a; system("pause"); return 0; }

Pour la variable const a, nous prenons l'adresse de la variable, la convertissons et l'affectons à un pointeur vers int, puis utilisons *p = 8; pour réaffecter la valeur à l'adresse de la variable a, puis affichons pour vérifier la valeur de a.

D'après le débogage ci-dessous, nous pouvons voir que la valeur de a a été changée en 8, mais le résultat affiché est toujours 7.

D'après le résultat, nous pouvons voir que le compilateur considère alors la valeur de a comme étant 7 telle que définie initialement, donc les opérations sur const a produisent la situation ci-dessus. Par conséquent, n'essayez jamais d'affecter une valeur à une variable const, car cela produira un comportement inattendu.

Si vous ne voulez pas que le compilateur remarque les opérations ci-dessus sur const, nous pouvons ajouter le mot-clé volatile avant const.

Le mot-clé volatile est l'opposé de const ; il signifie modifiable et facilement modifié. Par conséquent, il ne sera pas optimisé par le compilateur, et le compilateur ne modifiera pas ses opérations sur la variable a.

Exemple

#include<iostream> using namespace std; int main(void) { volatile const int a = 7; int *p = (int*)&a; *p = 8; cout<<a; system("pause"); return 0; }

Le résultat affiché est 8, comme nous l'attendions.

2. const modifie les variables pointeur

La modification par const de variables pointeur présente les trois cas suivants.

  • A : Si const modifie ce que le pointeur pointe, alors le contenu est immuable.
  • B : Si const modifie le pointeur, alors le pointeur est immuable.
  • C : Si const modifie à la fois le pointeur et ce qu’il pointe, alors le pointeur et le contenu pointé sont tous deux immuables.

Pour A :

const int *p = 8;

Alors le contenu pointé par le pointeur, 8, ne peut pas être modifié. En bref, « gauche fixe la valeur », car const se trouve à gauche du signe *.

Pour B :

int a = 8;
int* const p = &a;
*p = 9; // 正确
int  b = 7;
p = &b; // 错误

Pour le pointeur const p, l’adresse mémoire vers laquelle il pointe ne peut pas être modifiée, mais son contenu peut être modifié. En bref, « droite fixe la direction », car const se trouve à droite du signe *.

Pour C :C’est la combinaison de A et B.

int a = 8;
const int * const  p = &a;

À ce stade, le contenu pointé par const p ainsi que l’adresse mémoire vers laquelle il pointe sont fixes et ne peuvent pas être modifiés.

Pour les trois cas A, B et C, selon les différentes positions de const par rapport au signe *, je résume trois phrases pour faciliter la mémorisation :« Gauche fixe la valeur, droite fixe la direction, const modifie les invariants. »。

3. Passage de paramètres const et valeurs de retour de fonction

Pour const modifiant les paramètres d'une fonction, cela peut être divisé en trois cas.

A : const modifie le passage par valeur. Généralement, ce cas n'a pas besoin de la modification const, car la fonction crée automatiquement une variable temporaire pour copier la valeur de l'argument.

Exemple

#include<iostream> using namespace std; void Cpf(const int a) { cout<<a; // ++a; est incorrect, a ne peut pas être modifié } int main(void) { Cpf(8); system("pause"); return 0; }

B : Lorsque le paramètre const est un pointeur, cela peut empêcher le pointeur d'être modifié accidentellement.

Exemple

#include<iostream> using namespace std; void Cpf(int *const a) { cout<<*a<<" "; *a = 9; } int main(void) { int a = 8; Cpf(&a); cout<<a; // a vaut 9 system("pause"); return 0; }

C : Pour le passage de paramètres de types personnalisés, un objet temporaire est nécessaire pour copier le paramètre. La construction de l'objet temporaire nécessite l'appel du constructeur, ce qui est une perte de temps. Par conséquent, nous utilisons le passage par référence avec const.

De plus, pour les types intégrés courants tels que int et double, nous n'utilisons pas le passage par référence.

Exemple

#include<iostream> using namespace std; class Test { public: Test(){} Test(int _m):_cm(_m){} int get_cm()const { return _cm; } private: int _cm; }; void Cmf(const Test& _tt) { cout<<_tt.get_cm(); } int main(void) { Test t(8); Cmf(t); system("pause"); return 0; }

Résultat de sortie8。

Pour const modifiant la valeur de retour d'une fonction.

La modification const des valeurs de retour se divise en trois cas.

R : const modifiant la valeur de retour d'un type intégré a le même effet que de ne pas la modifier.

Exemple

#include<iostream> using namespace std; const int Cmf() { return 1; } int Cpf() { return 0; } int main(void) { int _m = Cmf(); int _n = Cpf(); cout<<_m<<" "<<_n; system("pause"); return 0; }

B : const modifie un type personnalisé comme valeur de retour. Dans ce cas, la valeur retournée ne peut pas être utilisée comme lvalue ; elle ne peut pas être affectée ni modifiée.

C : const modifie le pointeur ou la référence retournés. Le fait de savoir s'il faut retourner un pointeur vers const dépend de ce que nous voulons que l'utilisateur fasse.

4. const modifie les fonctions membres de classe

const appliqué à une fonction membre de classe vise à empêcher la fonction membre de modifier la valeur de l'objet appelé. Si nous ne voulons pas modifier la valeur d'un objet appelant, toutes les fonctions membres doivent être déclarées comme fonctions membres const.

Remarque :Le mot-clé const ne peut pas être utilisé avec le mot-clé static, car le mot-clé static modifie les fonctions membres statiques, et les fonctions membres statiques ne contiennent pas de pointeur this, c'est-à-dire qu'elles ne peuvent pas être instanciées. Une fonction membre const doit être spécifique à une instance particulière.

La fonction suivante get_cm()const; utilise une fonction membre const :

Exemple

#include<iostream> using namespace std; class Test { public: Test(){} Test(int _m):_cm(_m){} int get_cm()const { return _cm; } private: int _cm; }; void Cmf(const Test& _tt) { cout<<_tt.get_cm(); } int main(void) { Test t(8); Cmf(t); system("pause"); return 0; }

Si get_cm() retire le modificateur const, alors même que le const _tt passé à Cmf ne modifie pas la valeur de l'objet, le compilateur considère toujours que la fonction va modifier la valeur de l'objet. Par conséquent, nous devrions, comme requis, faire de toutes les fonctions qui n'ont pas besoin de modifier le contenu de l'objet des fonctions membres const.

Que se passe-t-il si une fonction membre veut modifier un membre particulier de l'objet ? Dans ce cas, nous pouvons utiliser le mot-clé mutable pour modifier ce membre. mutable signifie aussi modifiable et facilement modifiable. Un membre modifié par le mot-clé mutable peut être dans un état de changement constant, comme dans l'exemple suivant.

Exemple

#include<iostream> using namespace std; class Test { public: Test(int _m,int _t):_cm(_m),_ct(_t){} void Kf()const { ++_cm; // Faux ++_ct; // Correct } private: int _cm; mutable int _ct; }; int main(void) { Test t(8,7); return 0; }

Ici, dans Kf()const, nous modifions la valeur de _ct via ++_ct;, mais modifier _cm via ++_cm provoquera une erreur, car ++_cm n'est pas modifié avec mutable.

Adresse de l'article original : https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html