C++

Qualificatifs C++ et spécificateurs de classe de stockage

Qualificatifs C++ et spécificateurs de classe de stockage

CV signifie Constant-Volatile. La déclaration d'un objet qui n'est pas précédé de const et/ou volatile est de type cv non qualifié. D'autre part, la déclaration d'un objet précédé de const et/ou volatile est un type qualifié cv. Si un objet est déclaré const, la valeur de son emplacement ne peut pas être modifiée. Une variable volatile est une variable dont la valeur est sous l'influence du programmeur, et ne peut donc pas être modifiée par le compilateur.Les spécificateurs de classe de stockage font référence à la vie, au lieu et à la manière dont un type existe. Les spécificateurs de classe de stockage sont static, mutable, thread_local et extern.

Cet article explique les qualificatifs C++ et les spécificateurs de classe de stockage. Ainsi, quelques connaissances préliminaires en C++ sont utiles pour vraiment apprécier l'article.

Contenu de l'article :

Qualificatifs :

const

Un objet déclaré constant est un objet dont le stockage (emplacement) de la valeur ne peut pas être modifié. Par exemple, dans la déclaration :

int const l'Int = 5;

La valeur de 5 dans le stockage pour theInt ne peut pas être modifiée.

volatil

Considérez l'énoncé suivant :

int portVal = 26904873;

Les compilateurs interfèrent parfois avec la valeur d'une variable dans l'espoir d'optimiser le programme. Le compilateur peut maintenir la valeur d'une variable comme constante alors qu'elle n'est pas censée être constante. Les valeurs d'objet liées aux ports IO mappés en mémoire ou aux routines de service d'interruption des périphériques peuvent être perturbées par le compilateur. Pour éviter de telles interférences, rendez la variable volatile, comme :

int volatile portVal;
portVal = 26904873;
ou comme :
int volatile portVal = 26904873;

Combiner const et volatile :

const et volatile peuvent apparaître dans une instruction comme suit :

int const volatile portVal = 26904873;

cv-qualificatifs

Une variable précédée de const et/ou volatile est de type cv qualifié. Une variable non précédée de const ou volatile ou des deux est de type cv-non qualifié.

Commande :

Un type peut être plus qualifié de CV qu'un autre :

Il n'a pas encore été conclu si const et volatile sont du même rang.

Tableau et objet instancié :

Lorsqu'un tableau est déclaré constant, comme dans l'instruction suivante, cela signifie que la valeur de chaque élément du tableau ne peut pas être modifiée :

const char arr[] = 'a', 'b', 'c', 'd' ;

Qu'il s'agisse d'un 'a', 'b', 'c' ou 'd', il ne peut toujours pas être changé en une autre valeur (caractère).

Une situation similaire s'applique à un objet instancié d'une classe. Considérez le programme suivant :

#inclure
en utilisant l'espace de noms std ;
classe Cla

Publique:
car ch0 = 'a';
car ch1 = 'b';
car ch2 = 'c';
car ch3 = 'd';
 ;
int main()

const Cla obj;
renvoie 0 ;

En raison de la déclaration « const Cla obj ; » avec const dans la fonction main(), ni 'a' ni 'b' ni 'c' ni 'd' ne peuvent être changés en une autre valeur.

Spécificateurs de classe de stockage :

Les spécificateurs de classe de stockage sont static, mutable, thread_local et extern.

le spécificateur de classe de stockage statique

Le spécificateur de classe de stockage statique permet à la variable de vivre après le passage de sa portée, mais elle n'est pas accessible directement.

Le programme suivant illustre cela, avec une fonction récursive :

#inclure
en utilisant l'espace de noms std ;
fonction int()

statique int stac = 10;
cout << stac < 50)

cout << '\n';
renvoie 0 ;

fonction();

int main()

fonction();
renvoie 0 ;

La sortie est :

10 20 30 40 50

Si une variable statique n'est pas initialisée à sa première déclaration, elle prend la valeur par défaut pour son type.

Le spécificateur statique peut également être utilisé avec les membres d'une classe ; l'utilisation ici est différente. Ici, il permet d'accéder au membre sans instanciation pour l'objet.

Le programme suivant illustre cela pour un membre de données :

#inclure
en utilisant l'espace de noms std ;
classe Cla

Publique:
statique const int num = 8;
 ;
int main()

cout << Cla::num << '\n';
renvoie 0 ;

La sortie est :

8

La donnée membre statique doit être constante. Notez que l'utilisation de l'opérateur de résolution de portée pour accéder à la variable statique en dehors de sa portée (dans la fonction principale).

Le programme suivant illustre l'utilisation de « static » pour une fonction membre :

#inclure
en utilisant l'espace de noms std ;
classe Cla

Publique:
méthode vide statique ()

cout << "Of static member function!" << '\n';

 ;
int main()

Cla::méthode();
renvoie 0 ;

La sortie est :

De la fonction membre statique!

Notez que l'utilisation de l'opérateur de résolution de portée pour accéder à la fonction membre statique en dehors de sa portée (dans la fonction principale).

Le spécificateur mutable

Rappelez-vous, d'en haut, que si un objet instancié commence par const, la valeur de l'un de ses membres de données normaux ne peut pas être modifiée. Et pour qu'un tel membre de données soit modifié, il doit être déclaré, mutable.

Le programme suivant illustre cela :

#inclure
en utilisant l'espace de noms std ;
classe Cla

Publique:
car ch0 = 'a';
car ch1 = 'b';
caractère mutable ch2 = 'c';
car ch3 = 'd';
 ;
int main()

const Cla obj;
obj.ch2 = 'z';
cout << obj.ch0 << " << obj.ch1 << " << obj.ch2 << " << obj.ch3 << " << '\n';
renvoie 0 ;

La sortie est :

'a"b"z"d'

Le spécificateur thread_local

Dans l'exécution normale d'un programme, un segment de code est exécuté, puis le segment de code suivant, suivi d'un autre segment de code après cela, et ainsi de suite. C'est un fil; le fil conducteur. Si deux segments de code s'exécutent en même temps (même durée), alors un deuxième thread est nécessaire. Le résultat du deuxième thread peut même être prêt avant le thread principal.

La fonction main() est comme le thread principal. Un programme peut avoir plus de deux threads pour un tel comportement asynchrone.

Le deuxième thread a besoin d'une étendue (étendue de bloc) pour fonctionner. Ceci est généralement fourni par la portée de la fonction, une fonction. Une variable dans une portée externe qui peut être vue dans la portée du deuxième thread.

Le programme court suivant illustre l'utilisation du spécificateur thread_local :

#inclure
#inclure
en utilisant l'espace de noms std ;
thread_local int inter = 1;
void thread_function()

inter = inter + 1;
cout << inter << "nd thread\n";

int main()

thread thr(&thread_function); // thr commence à s'exécuter
cout << inter << "st or main thread\n";
thr.rejoindre(); // le thread principal attend que le thread se termine
renvoie 0 ;

La sortie est :

1er ou fil principal
2ème fil

La variable, inter, précédée de thread_local, signifie qu'inter a une instance distincte dans chaque thread. Et qu'il peut être modifié dans différents threads pour avoir des valeurs différentes. Dans ce programme, on lui attribue la valeur 1 dans le thread principal et modifié à la valeur 2 dans le deuxième thread.

Un thread a besoin d'un objet spécial pour fonctionner. Pour ce programme, la bibliothèque incluse par « #include ” a une classe appelée thread, à partir de laquelle l'objet thr a été instancié. Le constructeur de cet objet prend une référence à la fonction de thread comme argument. Le nom de la fonction de thread dans ce programme est thread_function().

La fonction membre join() pour l'objet spécial, à sa position utilisée, fait attendre le thread principal que le deuxième thread ait fini de s'exécuter avant de continuer à s'exécuter, sinon, la fonction main() peut se terminer sans que le (second) thread n'ait a donné son résultat.

Le spécificateur externe

En termes simples, pour une déclaration, la mémoire n'est pas allouée pour la variable ou la fonction, tandis que pour une définition, la mémoire est allouée. Le mot réservé externe permet de déclarer une variable globale ou une fonction dans un fichier mais définie dans un autre. Ces fichiers sont appelés unités de traduction pour l'application C++ complète.

Tapez le programme suivant et enregistrez-le sous le nom de fichier mainFile :

#inclure
en utilisant l'espace de noms std ;
int monInt;
const char ch;
annuler maFn();
int main()

maFn();
renvoie 0 ;

La variable myInt, la variable constante ch et la fonction myFn() ont été déclarées sans être définies.

Tapez le programme suivant avec les définitions et enregistrez-le sous le nom de fichier otherFile dans le même répertoire :

#inclure
en utilisant l'espace de noms std ;
int monInt = 10;
const char ch = 'c';
annuler maFn()

cout << "myFn() says " << myInt << " and " << ch <<'\n';

Essayez de compiler l'application sur le terminal (invite de commande DOS) avec la commande suivante, et notez qu'elle peut ne pas compiler :

fichier principal g++.cpp autreFichier.cpp -o complet.EXE

Maintenant, faites précéder les trois déclarations dans mainFile du mot "extern", comme suit :

extern int monInt;
extern const char ch;
extern void myFn();

Ré-enregistrer le fichier principal. Compilez l'application avec :

fichier principal g++.cpp autreFichier.cpp -o complet.EXE

(C'est ainsi que des fichiers séparés pour la même application sont compilés en C++)

Et il devrait compiler. Maintenant, lancez l'application, complétez.exe, et la sortie devrait être :

myFn() dit 10 et c

Notez qu'avec l'utilisation de "extern", une variable constante peut être déclarée dans un fichier mais définie dans un autre. Lors du traitement de la déclaration et de la définition de fonction dans différents fichiers, l'utilisation de extern est facultative.

Quand utiliser l'externe? Utilisez-le lorsque vous n'avez pas de fichiers d'en-tête avec des déclarations globales.

"extern" est également utilisé avec les déclarations de modèles - voir plus loin.

Conclusion:

Une variable précédée de const et/ou volatile est de type qualifié cv. Une variable, non précédée de const ou volatile ou des deux, est de type cv-non qualifié.

Les spécificateurs de classe de stockage sont static, mutable, thread_local et extern. Ceux-ci affectent la durée de vie (durée), le lieu et le mode d'emploi des variables dans une application.

Émulez les clics de souris en survolant à l'aide de la souris sans clic dans Windows 10
L'utilisation d'une souris ou d'un clavier dans la mauvaise posture d'une utilisation excessive peut entraîner de nombreux problèmes de santé, notamme...
Ajoutez des gestes de souris à Windows 10 à l'aide de ces outils gratuits
Ces dernières années, les ordinateurs et les systèmes d'exploitation ont considérablement évolué. Il fut un temps où les utilisateurs devaient utilise...
Contrôlez et gérez le mouvement de la souris entre plusieurs moniteurs dans Windows 10
Gestionnaire de souris à double affichage vous permet de contrôler et de configurer le mouvement de la souris entre plusieurs moniteurs, en ralentissa...