Classes de Stockage en C++
Salut à toi, aspirant(e)s programmeur(euse)s ! Aujourd'hui, nous allons entreprendre un voyage passionnant à travers le monde des classes de stockage en C++. Ne t'inquiète pas si tu es nouveau dans le domaine de la programmation ; je vais être ton guide amical, expliquant tout étape par étape. Mettons-nous à l'eau !
Quelles sont les Classes de Stockage ?
Avant de rentrer dans les détails, comprehensionnons ce qu'are les classes de stockage. En C++, les classes de stockage définissent la portée (visibilité) et la durée de vie des variables et des fonctions au sein d'un programme. Elles indiquent au compilateur comment stocker la variable, si elle est accessible depuis d'autres fichiers, et combien de temps elle devrait exister en mémoire.
Maintenant, explorons chaque classe de stockage en détail.
La Classe de Stockage auto
Le mot-clé auto
en C++ a changé de signification au fil du temps. Dans le C++ moderne (C++11 et suivant), il est utilisé pour l'inférence de type. Cependant, dans les versions plus anciennes, il était un spécificateur de classe de stockage.
Ancienne utilisation (avant C++11) :
int main() {
auto int x = 5; // Équivalent à : int x = 5;
return 0;
}
Dans cette ancienne utilisation, auto
déclarait explicitement une variable avec une durée de stockage automatique. Cependant, c'était la valeur par défaut pour les variables locales, donc il était rarement utilisé.
Utilisation moderne (C++11 et suivant) :
int main() {
auto x = 5; // x est inféré comme un int
auto y = 3.14; // y est inféré comme un double
auto z = "Hello"; // z est inféré comme un const char*
return 0;
}
Dans le C++ moderne, auto
permet au compilateur de déduire le type de la variable en fonction de son initialisateur. C'est particulièrement utile avec des types complexes ou lorsque le type pourrait changer à l'avenir.
La Classe de Stockage register
Le mot-clé register
est un hint au compilateur que cette variable sera utilisée fréquemment et devrait être conservée dans un registre CPU pour un accès plus rapide.
#include <iostream>
int main() {
register int counter = 0;
for(int i = 0; i < 1000000; i++) {
counter++;
}
std::cout << "Compteur : " << counter << std::endl;
return 0;
}
Dans cet exemple, nous suggérons au compilateur que counter
devrait être conservé dans un registre. Cependant, les compilateurs modernes sont généralement suffisamment intelligents pour faire ces optimisations d'eux-mêmes, donc register
est rarement utilisé en pratique.
La Classe de Stockage static
Le mot-clé static
a des significations différentes en fonction de son utilisation :
1. Variables Locales Statiques
#include <iostream>
void countCalls() {
static int calls = 0;
calls++;
std::cout << "Cette fonction a été appelée " << calls << " fois." << std::endl;
}
int main() {
for(int i = 0; i < 5; i++) {
countCalls();
}
return 0;
}
Dans cet exemple, calls
est initialisée une seule fois et conserve sa valeur entre les appels de fonction. La sortie sera :
Cette fonction a été appelée 1 fois.
Cette fonction a été appelée 2 fois.
Cette fonction a été appelée 3 fois.
Cette fonction a été appelée 4 fois.
Cette fonction a été appelée 5 fois.
2. Membres de Classe Statiques
class MyClass {
public:
static int objectCount;
MyClass() {
objectCount++;
}
};
int MyClass::objectCount = 0;
int main() {
MyClass obj1;
MyClass obj2;
MyClass obj3;
std::cout << "Nombre d'objets créés : " << MyClass::objectCount << std::endl;
return 0;
}
Ici, objectCount
est partagée entre toutes les instances de MyClass
. La sortie sera :
Nombre d'objets créés : 3
La Classe de Stockage extern
Le mot-clé extern
est utilisé pour déclarer une variable ou une fonction globale dans un autre fichier.
Fichier : globals.cpp
int globalVar = 10;
Fichier : main.cpp
#include <iostream>
extern int globalVar; // Déclaration de globalVar
int main() {
std::cout << "Valeur de la variable globale : " << globalVar << std::endl;
return 0;
}
Dans cet exemple, globalVar
est définie dans globals.cpp
et déclarée comme extern
dans main.cpp
. Cela permet à main.cpp
d'utiliser la variable définie dans un autre fichier.
La Classe de Stockage mutable
Le mot-clé mutable
permet à un membre d'un objet const
d'être modifié.
class Person {
public:
Person(int age) : age(age), cacheValid(false) {}
int getAge() const {
if (!cacheValid) {
cachedAge = heavyComputation();
cacheValid = true;
}
return cachedAge;
}
private:
int age;
mutable int cachedAge;
mutable bool cacheValid;
int heavyComputation() const {
// Simuler un calcul lourd
return age;
}
};
int main() {
const Person p(30);
std::cout << p.getAge() << std::endl; // Cela est permis
return 0;
}
Dans cet exemple, même si p
est const
, nous pouvons modifier cachedAge
et cacheValid
car ils sont marqués comme mutable
.
Résumé
Résumons les classes de stockage que nous avons apprises dans un tableau pratique :
Classe de Stockage | Objectif |
---|---|
auto | Inférence de type (C++ moderne) |
register | Hint pour un accès plus rapide (rarement utilisé) |
static | Préserver la valeur entre les appels de fonction ou partagée entre les instances de classe |
extern | Déclarer des variables ou des fonctions d'autres fichiers |
mutable | Permettre la modification dans les objets const
|
Souviens-toi, comprendre les classes de stockage est crucial pour gérer la mémoire efficacement et contrôler la portée de tes variables. Alors que tu continues ton parcours en C++, tu trouveras ces concepts devenant naturels. Bon codage !
Credits: Image by storyset