Académique Documents
Professionnel Documents
Culture Documents
Classes et objets
Classes
1. Déclaration de classe
Pour créer un objet, il faut d'abord créer une classe !
Exemple:
pour construire une maison, vous avez besoin d'un plan d'architecte?
Imaginez simplement que la classe c'est le plan et que l'objet c'est la
maison.
« Créer une classe », c'est donc dessiner les plans de l'objet.
Une fois que vous avez les plans, vous pouvez faire
autant de maisons que vous voulez en vous basant sur
ces plans. Pour les objets c'est identique : une fois que
vous avez fait la classe (le plan), vous pouvez créer autant
d'objets du même type que vous voulez.
• Il est impossible d'initialiser les attributs ici. Cela doit être fait via ce qu'on appelle un constructeur,
comme on le verra un peu plus loin.
• Comme on utilise un objet string, il faut bien penser à rajouter un #include <string>dans votre fichier.
Classes
2. Ajout de méthodes et d'attributs
2.1 Les méthodes
Les méthodes lisent et modifient les attributs. Voici quelques actions
réalisables avec notre personnage :
recevoirDegats : le personnage prend un certain nombre de dégâts et
donc perd de la vie.
En résumé
Un objet est un mix de variables (les attributs) et de fonctions
(les méthodes).
La plupart du temps, les méthodes lisent et modifient les
attributs de l'objet pour le faire évoluer.
Un objet est au final un petit système intelligent et autonome,
capable de surveiller tout seul son bon fonctionnement.
Classes
3. Droits d'accès et encapsulation
Création de la classe :
Classes
3. Droits d'accès et encapsulation
Utilisation de l'objet :
Classes
3. Droits d'accès et encapsulation
Tenez, pourquoi n'essaierait-on pas ce code ?
Allez, on met tout dans un même fichier (en prenant soin de définir la classe avant le main()).
Classes
3. Droits d'accès et encapsulation
Essayez, vous verrez que le compilateur vous ressort la même erreur que
tout à l'heure : « ton bidule est private... bla bla bla... pas le droit
d'appeler un élément private depuis l'extérieur de la classe ».
Mais alors... cela veut dire qu'on ne peut pas modifier la vie du
personnage depuis le main ()?
Il existe une règle de POO qui précise que les attributs doivent être
encapsulées dans la classe pour éviter une utilisation extérieure.
C’est une forme de protection permettant d’éviter une utilisation
incorrecte ou non prévue par le programmeur de la classe.
On appliquera ce principe en déclarant l’ensemble des attributs en
private.
Classes
Exemple: #include <iostream>
using namespace std;
class Simple_math
{
private:
int r;
public:
void sum(int a, int b)
{ r = a + b; };
void divided(int a, int b)
{ if (b==0){
r = 0;}
else
{r = a / b;}
};
void print ()
{ cout << "\n====\n"<< r << "\n====\n" ; };
};
//============================================
int main()
{
Simple_math sm;
sm.sum( 3 , 2 );
sm.print();
sm.divided ( 3 , 0);
sm.print();
};
Classes
4. Séparations prototypes et définitions
Séparer les méthodes en prototypes et définitions dans deux fichiers différents,
pour avoir un code plus modulaire ;
Implémenter les méthodes de la classe Personnage (c'est-à-dire écrire le code à
l'intérieur parce que, pour le moment, il n'y a rien).
À ce stade, notre classe figure dans le fichier main.cpp, juste au-dessus dumain().
Et les méthodes sont directement écrites dans la définition de la classe.
Pour améliorer cela, il faut tout d'abord clairement séparer le main() (qui se trouve
dans main.cpp) des classes. Pour chaque classe, on va créer :
un header (fichier*.h) qui contiendra les attributs et les prototypes de la classe ;
un fichier source (fichier*.cpp) qui contiendra la définition des méthodes et leur
implémentation.
Je vous propose d'ajouter à votre projet deux fichiers nommés très exactement :
Personnage.h;
Personnage.cpp.
Sous Code::Blocks, on passe par les menus File>New File, on saisis par exemple le
nom Personnage.h avec son extension et on réponds « Oui » quand Code::Blocks
nous demande si on veux ajouter le nouveau fichier au projet en cours (figure
suivante).
Classes
4. Séparations prototypes et définitions
Personnage.h
Le fichier .h va donc contenir la déclaration de la classe avec les attributs et les
prototypes des méthodes.
Dans les .h, il est recommandé de ne jamais
mettre la directive using namespace std;car cela
pourrait avoir des effets néfastes, par la suite,
lorsque vous utiliserez la classe.
Par conséquent, il faut rajouter le préfixe std::
devant chaque string du .h. Sinon, le compilateur
vous sortira une erreur du type :
string does not name a type.
Classes
4. Séparations prototypes et définitions
Personnage.cpp
C'est là qu'on va écrire le code de nos méthodes (on dit qu'on implémente les
méthodes).
Personnage.cpp
Classes
5.1. Constructeur
Si on en profitait pour coder ce constructeur dans Personnage.cpp ?
Voici à quoi pourrait ressembler son implémentation :
Personnage.cpp
J'ai choisi de mettre la vie et le mana à 100, le maximum, ce qui est logique. J'ai affecté
par défaut une arme appelée « Épée rouillée » qui fait 10 de dégâts à chaque coup.
Et voilà ! Notre classe Personnage a un constructeur qui initialise les attributs, elle est
désormais pleinement utilisable.
Maintenant, à chaque fois que l'on crée un objet de type Personnage, celui-ci est
initialisé à 100 points de vie et de mana, avec l'arme « Épée rouillée ».
Nos deux compères david et goliath commencent donc à égalité lorsqu'ils sont créés
dans le main():
Classes
5.1. Constructeur
Autre façon d'initialiser avec un constructeur : la liste d'initialisation
Le C++ permet d'initialiser les attributs de la classe d'une autre manière (un peu
déroutante) appelée liste d'initialisation. C'est une technique que je vous
recommande d'utiliser quand vous le pouvez
Dans ce cas:
Maintenant, supposons que l'on veuille donner dès le départ une meilleure
arme à Goliath ; on indique entre parenthèses le nom et la puissance de
cette arme :
Classes
5.1. Constructeur
Le constructeur de copie
Je vous ai dit au début de ce chapitre, que le compilateur créait
automatiquement un constructeur par défaut qui ne fait rien. Ce n'est pas
tout, il crée aussi ce qu'on appelle un "constructeur de copie". C'est une
surcharge du constructeur qui initialise notre objet en copiant les valeurs
des attributs de l'autre objet.
Par exemple si l'on souhaite que david soit une copie conforme de goliath,
il nous suffit d'écrire:
Personnage david (goliath); //On crée david en copiant tous les attributs de goliath
Classes
5.2. Le destructeur
Créer un destructeur
Bien que ce soit inutile dans notre cas (je n'ai pas utilisé d'allocation
dynamique pour ne pas trop compliquer les choses tout de suite), je vais
vous montrer comment on crée un destructeur. Voici les règles à suivre :
~
Classes
5.3. Les méthodes constantes