Pointeurs const et volatile
Les mot clé const et volatiles changent la façon dont les pointeurs sont traités. La const
mot clé spécifie que le pointeur ne peut pas être modifié après l’initialisation ; le pointeur est protégé contre la modification par la suite.
L’mot clé volatile
spécifie que la valeur associée au nom qui suit peut être modifiée par des actions autres que celles de l’application utilisateur. Par conséquent, le volatile
mot clé est utile pour déclarer des objets en mémoire partagée accessibles par plusieurs processus ou zones de données globales utilisées pour la communication avec des routines de service d’interruption.
Lorsqu’un nom est déclaré en tant que volatile
, le compilateur recharge la valeur de la mémoire chaque fois qu’il est accessible par le programme. Cela réduit considérablement les optimisations possibles. Toutefois, lorsque l'état d'un objet peut changer de manière inattendue, c'est la seule façon de garantir des performances prévisibles du programme.
Pour déclarer l’objet pointé par le pointeur en tant que const
ou volatile
, utilisez une déclaration du formulaire :
const char *cpch;
volatile char *vpch;
Pour déclarer la valeur du pointeur ( autrement dit, l’adresse réelle stockée dans le pointeur) en tant que const
ou volatile
, utilisez une déclaration du formulaire :
char * const pchc;
char * volatile pchv;
Le langage C++ empêche les affectations qui autorisent la modification d’un objet ou d’un pointeur déclaré en tant que const
. De telles assignations supprimeraient les informations avec lesquelles l'objet ou le pointeur a été déclaré, ce qui entraînerait la violation de l'objectif de la déclaration d'origine. Prenons les déclarations suivantes :
const char cch = 'A';
char ch = 'B';
Étant donné les déclarations précédentes de deux objets (cch
de type const char et ch
, de type char), les déclarations/initialisations suivantes sont valides :
const char *pch1 = &cch;
const char *const pch4 = &cch;
const char *pch5 = &ch;
char *pch6 = &ch;
char *const pch7 = &ch;
const char *const pch8 = &ch;
Les déclarations/initialisations suivantes sont erronées.
char *pch2 = &cch; // Error
char *const pch3 = &cch; // Error
La déclaration de pch2
déclare un pointeur par l'intermédiaire duquel un objet constant peut être modifié et par conséquent désactivé. La déclaration de pch3
spécifie que le pointeur est constant, et non l’objet ; la déclaration n’est pas autorisée pour la même raison que la pch2
déclaration n’est pas autorisée.
Les huit assignations suivantes indiquent l'assignation par l'intermédiaire du pointeur et la modification de la valeur du pointeur pour les déclarations précédentes ; pour le moment, supposons que l'initialisation est correcte de pch1
à pch8
.
*pch1 = 'A'; // Error: object declared const
pch1 = &ch; // OK: pointer not declared const
*pch2 = 'A'; // OK: normal pointer
pch2 = &ch; // OK: normal pointer
*pch3 = 'A'; // OK: object not declared const
pch3 = &ch; // Error: pointer declared const
*pch4 = 'A'; // Error: object declared const
pch4 = &ch; // Error: pointer declared const
Les pointeurs déclarés comme , ou en tant que volatile
mélange de const
et volatile
, obéissent aux mêmes règles.
Les pointeurs vers const
des objets sont souvent utilisés dans les déclarations de fonction comme suit :
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
L’instruction précédente déclare une fonction, strcpy_s, où deux des trois arguments sont de type pointeur vers char
. Étant donné que les arguments sont passés par référence et non par valeur, la fonction est libre de modifier les deux strDestination
et strSource
si strSource
elles n’ont pas été déclarées comme const
. La déclaration de strSource
tel const
garantit que l’appelant ne strSource
peut pas être modifié par la fonction appelée.
Remarque
Étant donné qu’il existe une conversion standard de typename* enconst
typename*, il est légal de passer un argument de type char *
à strcpy_s. Toutefois, l’inverse n’est pas vrai ; aucune conversion implicite n’existe pour supprimer l’attribut const
d’un objet ou d’un pointeur.
Un const
pointeur d’un type donné peut être affecté à un pointeur du même type. Toutefois, un pointeur qui ne peut pas const
être affecté à un const
pointeur. L'exemple de code suivant montre des assignations correctes et incorrectes :
// const_pointer.cpp
int *const cpObject = 0;
int *pObject;
int main() {
pObject = cpObject;
cpObject = pObject; // C3892
}
L'exemple suivant montre comment déclarer un objet comme const si vous avez un pointeur désignant un pointeur vers un objet.
// const_pointer2.cpp
struct X {
X(int i) : m_i(i) { }
int m_i;
};
int main() {
// correct
const X cx(10);
const X * pcx = &cx;
const X ** ppcx = &pcx;
// also correct
X const cx2(20);
X const * pcx2 = &cx2;
X const ** ppcx2 = &pcx2;
}
Voir aussi
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour