[Plan du site]
Vous êtes ici ---
> Le Site du Zér0
> Les tutoriels
> Officiels
> Programmation
> Lecture du tutoriel
Eléments statiques et constants
Vous tenez le coup ?

Courage, vos efforts seront bientôt largement récompensés.
Ce chapitre va d'ailleurs vous permettre de souffler un peu. Vous allez découvrir quelques notions spécifiques aux classes en C++ : les attributs et méthodes statiques et constants. Ce sont ce que j'appellerais des "points particuliers" du C++. Ce ne sont pas des détails pour autant, ce sont des choses à connaître.
Car oui, tout ce que je vous apprends là, vous allez en avoir besoin et vous allez largement le réutiliser. Je suis sûr aussi que vous en comprendrez mieux l'intérêt lorsque vous pratiquerez pour de bon.
N'allez pas croire que les programmeurs ont inventé des trucs un peu complexes comme ça juste pour le plaisir de programmer de façon tordue
On en a rapidement parlé lorsqu'on a introduit les accesseurs (méthodes get/set pour accéder aux attributs), mais je pense que ça vaut le coup de faire le point complètement sur cette notion ici. Ca sera court, mais au moins vous le retiendrez bien et vous ne serez pas surpris si vous voyez des gens en faire.
Euh de quoi je parle ? Des
méthodes constantes !

Ce sont des méthodes qui possèdent le mot-clé const
à la fin de leur prototype et de leur déclaration.
Quand vous dites "ma méthode est constante", vous indiquez au compilateur que votre méthode ne modifie pas l'objet, c'est-à-dire qu'elle ne modifie la valeur d'aucun de ses attributs. Par exemple, une méthode qui se contente d'afficher des informations à l'écran sur l'objet est une méthode constante : elle ne fait que lire les attributs. En revanche, une méthode qui met à jour le niveau de vie d'un personnage ne peut pas être constante
Ca s'utilise comme ceci :
Code : C++1
2
3
4
5
6
7
8
9 | // Prototype de la méthode (dans le .h) :
void maMethode(int parametre) const;
// Déclaration de la méthode (dans le .cpp) :
void maMethode(int parametre) const
{
}
|
On utilisera souvent le mot-clé const sur les méthodes accesseur (getAttribut), ces méthodes qui se contentent de renvoyer la valeur d'un attribut pour respecter le principe d'encapsulation qui dit que l'attribut doit être privé.
Code : C++1
2
3
4 | int Personnage::getVie() const
{
return m_vie;
}
|
Concrètement, ça sert à quoi de créer des méthodes constantes ?
Ca sert à 2 choses principalement :
- Pour vous : vous savez que votre méthode ne fait que lire les attributs, et vous vous interdisez dès le début de les modifier. Si par erreur vous en modifiez, le compilateur plantera en vous disant que vous ne respectez pas la règle que vous vous êtes fixée. Et ça c'est bien.
- Pour les utilisateurs de votre classe : c'est très important aussi pour eux, ça leur indique que la méthode ne fait que renvoyer un résultat mais qu'elle ne modifie pas l'objet. Dans une documentation, le mot-clé const apparaît dans le prototype de la méthode et est un excellent indicateur de ce qu'elle fait, ou plutôt de ce qu'elle ne peut pas faire (ça pourrait se traduire par : "cette méthode ne modifiera pas votre objet").
Ah les méthodes statiques... Alors ça, c'est un peu spécial

Ce sont des méthodes qui appartiennent à la classe mais pas aux objets instanciés à partir de la classe... En fait, ce sont de bêtes "fonctions" rangées dans des classes qui n'ont pas accès aux attributs de la classe. Ca s'utilise d'une manière un peu particulière.
Le mieux est encore un exemple je pense !
Créer une méthode statique
Dans le .h, le prototype d'une méthode statique ressemble à ceci :
Code : C++1
2
3
4
5
6 | class MaClasse
{
public:
MaClasse();
static void maMethode();
};
|
Son implémentation dans le .cpp ne possède pas en revanche de mot-clé
static :
Code : C++1
2
3
4 | void Personnage::maMethode() // Ne pas remettre "static" dans l'implémentation
{
cout << "Bonjour !" << endl;
}
|
Ensuite, dans le main, la méthode statique s'appelle comme ceci :
Code : C++1
2
3
4
5
6 | int main()
{
Personnage::maMethode();
return 0;
}
|
Mais... on n'a pas créé d'objet de type Personnage et on appelle la méthode quand même ? C'est quoi ce bazar ?
C'est justement ça la particularité des méthodes statiques. Pour les utiliser, pas besoin de créer un objet. Il suffit juste de faire précéder le nom de la méthode par le nom de la classe suivi de deux deux-points.
D'où le :
Personnage::maMethode();
Cette méthode, comme je vous le disais, ne peut pas accéder aux attributs de la classe. C'est vraiment une bête fonction, mais
rangée dans une classe. Ca permet de regrouper les fonctions dans des classes, par thème, et aussi d'éviter des conflits de nom.
Quelques exemples de l'utilité des méthodes statiques
Les méthodes statiques peuvent vous paraître un tantinet stupides. En effet, à quoi bon avoir inventé le modèle objet si c'est pour autoriser les gens à créer de bêtes "fonctions" regroupées dans des classes ?
La réponse, c'est qu'on a toujours besoin d'utiliser de "bêtes" fonctions même en modèle objet, mais pour être un peu cohérent on les regroupe dans des classes en précisant qu'elles sont statiques.
Il y a en effet des fonctions qui ne nécessitent pas de créer un objet, pour lesquelles ça n'aurait pas de sens.
Des exemples ?
- Il existe dans la librairie Qt une classe QDate qui permet de manipuler des dates. On peut comparer des dates entre elles (surcharge d'opérateur) etc etc. Cette classe propose aussi un certain nombre de méthodes statiques, comme currentDate qui renvoie la date actuelle. Pas besoin de créer un objet pour avoir cette information ! Il suffit donc de taper QDate::currentDate() pour récupérer la date actuelle

- Toujours avec Qt, la classe QDir, qui permet de manipuler les dossiers du disque dur, propose quelques méthodes statiques. Par exemple, on trouve QDir::drives() qui renvoie la liste des disques présents sur l'ordinateur (par exemple "C:\", "D:\", etc). Là encore, ça n'aurait pas eu d'intérêt d'instancier un objet à partir de la classe car ce sont des informations générales.
- etc etc.
Mmmh mais c'est que ça donne envie de travailler avec Qt tout ça
Il existe aussi ce qu'on appelle des
attributs statiques.
Tout comme les méthodes statiques, les attributs statiques appartiennent à la classe et non aux objets créés à partir de la classe.
Créer un attribut statique dans une classe
C'est assez simple en fait : il suffit de rajouter le mot-clé
static au début de la ligne.
Un attribut static, bien qu'il soit accessible de l'extérieur, peut très bien être déclaré
private ou
protected. Appelez ça une exception, car c'en est bien une
Exemple :
Code : C++1
2
3
4
5
6
7
8
9 | class MaClasse
{
public:
MaClasse();
private:
static int monAttribut;
};
|
Sauf qu'on ne peut pas initialiser l'attribut statique ici. Il faut le faire dans l'espace global, c'est-à-dire en dehors de toute classe ou fonction,
en dehors du main notamment.
Code : C++1
2 | // Initialiser l'attribut en dehors de toute fonction ou classe (espace global)
int Personnage::monAttribut = 5;
|
Un attribut déclaré comme statique se comporte comme une variable globale, c'est-à-dire une variable accessible partout dans le code.
Ouaaaah ! Stop !
Tu nous avais pas dit à un moment que les variables globales c'était le mal absolu et que même si ça existait il fallait préférer se pendre plutôt que de les utiliser ?
En effet. Bien qu'il y ait toujours des cas où ça se révèle utile et indispensable, c'est très rarement le cas. De manière générale, fuyez ces variables globales comme la peste.
Créer un attribut statique dans une méthode d'une classe
Il y a un cas particulier : on peut aussi créer une variable statique à l'intérieur d'une méthode d'une classe. Cette fois c'est un peu moins bourrin : la variable ne sera accessible que depuis la méthode où elle se trouve.
Le truc, c'est que la variable ne sera pas supprimée de la mémoire à la fin de la méthode. Elle reste en mémoire et sera réutilisée la prochaine fois que la méthode sera appelée, et ce
quel que soit l'objet qui y fait appel.
Pour ceux qui s'en souviennent, c'est exactement le même principe que les variables statiques qu'on avait vues dans le cours de C.
Un exemple sera plus parlant
Code : C++ - MaClasse.h1
2
3
4
5 | class MaClasse
{
public:
void methode();
};
|
Code : C++ - MaClasse.cpp1
2
3
4
5
6
7 | void MaClasse::methode()
{
static int compteur = 0;
compteur++;
cout << compteur << endl;
}
|
Code : C++ - main.cpp1
2
3
4
5
6
7
8
9 | int main()
{
MaClasse objet1, objet2;
objet1.methode();
objet2.methode();
return 0;
}
|
Résultat à l'écran :
Code : Console
Lors de l'appel de la méthode du premier objet, la variable statique compteur est créée et le nombre 1 est affiché.
Lors de l'appel de la méthode du second objet, la variable statique compteur existe déjà en mémoire donc elle n'est pas recréée. C'est celle créée pour le premier objet qui est réutilisée ici. La preuve : le compteur est incrémenté à nouveau et l'écran affiche 2, ce qui signifie que la variable compteur est la même dans les 2 objets.
Ces points un peu particuliers (mais pas bien compliqués) étant vus, je crois que vous avez suffisamment de bagage théorique pour commencer à pratiquer vraiment le C++.
C'est justement l'objectif de la partie suivante, qui va porter sur la librairie Qt dont je vous parle depuis un petit moment maintenant

Cette librairie est vraiment immense et va vous permettre entre autres choses de créer des fenêtres afin de rendre vos applications bien plus sympathiques d'utilisation.
Vous en avez bavé pendant cette partie, vous avez dû emmagasiner pas mal de nouvelles connaissances, aussi vous pouvez considérer que la partie qui va suivre est la... récompense

Tout ce que vous avez appris jusqu'ici va vous resservir, donc n'hésitez pas à relire les chapitres de cette partie que vous n'auriez pas trop bien compris. Parfois ça se débloque au bout de quelques lectures ! Et si ça débloque pas, tant pis, passez à la pratique quand même, je suis sûr que vous comprendrez mieux tous ces concepts du C++ en travaillant sur du concret !