Membres statiques
Membres statiques
Une variable qui fait partie d’une classe mais pas d’un objet de cette classe est appelée membre statique. Il existera une seule copie de cette variable. De la même façon, une fonction qui a besoin d’accéder aux membres d’une classe mais qui n’aura pas besoin d’être appelée pour un objet particulier sera définie comme fonction membre statique. En fait, ces fonctions membres ne recevront pas le pointeur sur l’objet this (voir section suivante), comme c’est le cas pour les autres fonctions membres. Par conséquent, elles ne pourront accéder qu’aux données statiques de l’objet.Il est impossible d’initialiser les données statiques d’une classe dans le constructeur de la classe, car le constructeur initialise les données des nouveaux objets, et ces données ne sont pas spécifiques à un objet particulier. L’initialisation des données statiques doit donc se faire lors de leur définition, qui se fait en dehors de la déclaration de la classe. Il faut préciser la classe à laquelle les données ainsi définies appartiennent, en les préfixant du nom de la classe, suivi de l’opérateur de résolution de portée (Date:: dans notre exemple).
Code 4.4 : fichier Date.h
#include<iostream> //Pour les entrées/sorties using namespace std; class Date { private: int jour, mois, annee; static Date date_par_defaut; //membre statique public: Date(int j=0,int m=0,int a=0); ~Date(); void DefinirDate(int j,int m,int a) { jour=j; mois=m; annee=a; } void LireDate() const { cout<<"Date: "<<jour<<" "<<mois<<" "<<annee<<endl; } //fonctions membres statiques static void DefinirDefaut(int,int,int); static void LireDefaut(); };
Notez que nous avons remplacé les prototypes des fonctions DefinirDate() et LireDate() dans la déclaration de classe directement par leurs définitions. Cela permet de les intégrer au code automatiquement puisqu’elles sont alors considérées comme inline. Dans cette classe, le membre statique est un objet Date.
Code 4.5 : fichier Date.cpp
#include"Date.h" //Inclusion de la déclaration de Date /***Initialisation du membre statique***/ Date Date::date_par_defaut(1,1,2009); /****Définition du constructeur****/ Date::Date(int j,int m,int a) { //Initialisation des données membres : jour=j ? j:date_par_defaut.jour; mois=m ? m:date_par_defaut.mois; annee=a ? a:date_par_defaut.annee; } /****Définition du destructeur****/ Date::~Date() { } /*Définition de la fonction membre statique DefinirDefaut()*/ void Date::DefinirDefaut(int jj,int mm,int aa) { Date::date_par_defaut=Date(jj,mm,aa); } /*Définition de la fonction membre statique LireDefaut()*/ void Date::LireDefaut( ) { cout << Date::date_par_defaut.jour << "/" << Date::date_par_defaut.mois; cout << "/" << Date::date_par_defaut.annee ; } int main() //Fonction principale { int j, m, a; char reponse; cout << "La date par défaut est: "; Date::LireDefaut(); cout << "\nVoulez vous en changer? (o/n): "; cin >> reponse; if(reponse==‘o’) { cout << "\nSaisissez la nouvelle date par défaut (ex:5 12 2010): "; cin >> j; cin >> m; cin >> a; Date::DefinirDefaut(j,m,a); cout << "\nLa nouvelle date par défaut est: " ; Date::LireDefaut(); //On vérifie la valeur du membre statique } Date date_standard=Date(); //on crée une instance //avec les valeurs par défaut Date date_perso=Date(5,3,2009); //on crée une instance //avec les arguments transmis cout << "\nVersion standard: "; date_standard.LireDate(); cout << "\nVersion perso: "; date_perso.LireDate(); }
Vous obtenez le résultat suivant :
La date par défaut est: 1/1/2009 Voulez vous en changer? (o/n): o Saisissez la nouvelle date par défaut (ex:5 12 2009): 10 3 2009 La nouvelle date par défaut est: 10/3/2009 Version standard: Date: 10 3 2009 Version perso: Date: 5 3 2009
Dans ce programme, vous créez deux objets Date : le premier avec les valeurs de la date par défaut, le second à partir des arguments transmis par le programme. Les fonctions membres LireDefaut() et DefinirDefaut() permettent d’accéder au membre statique date_par_defaut et de le modifier.
La définition des données membres statiques suit les mêmes règles que la définition des variables globales lorsqu’elles sont déclarées dans la partie publique. Autrement dit, elles se comportent comme des variables déclarées externes. Elles sont donc accessibles dans tous les fichiers du programme. De même, elles ne doivent être définies qu’une seule fois dans tout le programme. Il ne faut donc pas les définir dans un fichier d’en-tête qui peut être inclus plusieurs fois dans des fichiers source, même si l’on protège ce fichier d’en-tête contre les inclusions multiples (voir section « Fichiers en-tête » précédemment).
À savoir
L’opérateur ? est au cœur des initialisations effectuées dans le constructeur. Reportez-vous au code 3.6 si vous en avez oublié la syntaxe.Le texte original de cette fiche pratique est extrait de
«Tout sur le C++» (Christine EBERHARDT, Collection
CommentCaMarche.net, Dunod, 2009)