Membres d’instance et statiques
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 27 sur 104.
Jusqu'à présent, chaque variable membre que tu as créée appartient à un objet spécifique. Lorsque tu crées deux objets Player, chacun possède son propre name et sa propre health. On les appelle des membres d'instance : ils existent séparément pour chaque instance de la classe.
Mais que faire si tu as besoin de données partagées entre tous les objets ? Par exemple, suivre le nombre total de joueurs.
C’est ici qu’interviennent les membres statiques. Un membre statique appartient à la classe elle-même, et non à un objet particulier.
class Player {
std::string name; // Membre d'instance - chaque joueur a le sien
int health; // Membre d'instance
static int playerCount; // Membre statique - partagé par TOUS les joueurs
public:
Player(std::string n) : name(n), health(100) {
playerCount++; // Incrémente lorsqu'un joueur est créé
}
~Player() {
playerCount--; // Décrémente lorsqu'un joueur est détruit
}
};La différence essentielle : les membres d’instance sont accessibles via un objet, tandis que les membres statiques peuvent être accessibles directement via le nom de la classe. Considérez les membres d’instance comme « un par objet » et les membres statiques comme « un par classe ».
| Membres d’instance | Membres statiques |
|---|---|
| Uniques à chaque objet | Partagés entre tous les objets |
| Créés lorsque l’objet est créé | Existent avant qu’un objet ne soit créé |
Accédés via l’objet : player.health | Accédés via la classe : Player::playerCount |
Les membres statiques sont utiles pour les compteurs, les valeurs de configuration ou toute donnée qui appartient logiquement à la classe plutôt qu’aux objets individuels.
Défi
FacileConstruisons un système d’inventaire de produits qui suit à la fois les détails de chaque produit et les statistiques globales de l’inventaire à l’aide de membres d’instance et de membres statiques.
Vous allez créer deux fichiers pour organiser votre code :
Product.h: définissez une classeProductqui gère les produits individuels tout en assurant également le suivi des données globales de l’inventaire. Votre classe doit comporter :- Membres d’instance :
name(chaîne de caractères) etprice(double) : propres à chaque produit - Un membre statique
totalProductsqui compte le nombre de produits actuellement existants - Un membre statique
totalValuequi suit le prix cumulé de tous les produits - Un constructeur qui prend un nom et un prix, initialise les membres d’instance et met à jour les deux compteurs statiques (incrémenter le nombre, ajouter le prix à la valeur totale)
- Un destructeur qui met à jour les compteurs statiques lorsqu’un produit est supprimé (décrémenter le nombre, soustraire le prix de la valeur totale)
- Une méthode
getInfo()qui renvoie une chaîne au format :"<name>: $<price>" - Une méthode statique
getInventoryStats()qui renvoie une chaîne :"Products: <count>, Total Value: $<value>"
- Membres d’instance :
main.cpp: démontrez comment les membres statiques sont partagés entre tous les objets, tandis que les membres d’instance restent propres à chacun. Lisez deux noms de produits et leurs prix depuis l’entrée (name1, price1, name2, price2 : chacun sur une ligne distincte), puis :- Affichez les statistiques initiales de l’inventaire en utilisant le nom de la classe :
Product::getInventoryStats() - Créez un bloc de portée avec des accolades et, à l’intérieur, créez un
Productavec le premier nom et le premier prix. Affichez ses informations ainsi que les statistiques actuelles de l’inventaire. - Après la fin du bloc (le premier produit est détruit), affichez
"After first scope:"suivi des statistiques de l’inventaire - Créez un autre
Productavec le deuxième nom et le deuxième prix. Affichez ses informations ainsi que les statistiques de l’inventaire. - Créez un troisième
Productavec le nom"Bonus"et le prix5.00. Affichez les statistiques finales de l’inventaire.
- Affichez les statistiques initiales de l’inventaire en utilisant le nom de la classe :
N’oubliez pas de définir vos membres statiques en dehors de la classe dans le fichier d’en-tête (après la définition de la classe). Formatez les prix avec deux décimales en utilisant std::fixed et std::setprecision(2) de <iomanip>.
Incluez votre fichier d’en-tête dans main.cpp à l’aide de #include "Product.h".
Essayez vous-même
#include <iostream>
#include <string>
#include "Product.h"
using namespace std;
int main() {
// Lire l'entrée
string name1;
double price1;
string name2;
double price2;
getline(cin, name1);
cin >> price1;
cin.ignore();
getline(cin, name2);
cin >> price2;
// TODO: Afficher les statistiques d'inventaire initiales en utilisant Product::getInventoryStats()
// TODO: Créer un bloc de portée avec des accolades
// À l'intérieur du bloc :
// - Créer un Product avec name1 et price1
// - Afficher ses infos en utilisant getInfo()
// - Afficher les statistiques d'inventaire actuelles
// TODO: After the block ends, print "After first scope:"
// Puis afficher les statistiques d'inventaire
// TODO: Créer un autre Product avec name2 et price2
// Afficher ses infos et les statistiques d'inventaire
// TODO: Créer un troisième Product avec le nom "Bonus" et le prix 5.00
// Afficher les statistiques d'inventaire finales
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d’accès en C++Spécificateurs d’accès en profondeurMasquage de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l’opérateur d’affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif – Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne