• Aucun résultat trouvé

Vocabulaire et définition d’une classe : champs et méthodes

4.7 L’aléatoire en C++

5.1.2 Vocabulaire et définition d’une classe : champs et méthodes

structures struct héritées du langageC et présentées dans la section3.1.4. Les structures présentées précédemment ne contiennent que des champs qui sont des emplacements dans la mémoire ; une classe contient de tels champs et ajoute à ceux-ci toutes les opérations naturelles que l’on peut effectuer dessus, les méthodes. C’est le principe de la programmation orientée objet : un objet (ici une classe) est la donnée jointe de variables et des fonctions qui agissent dessus.

Si nous osions un parallèle mathématique, nous dirions que c’est la même chose qu’une structure struct correspond à Z vu comme un ensemble d’éléments alors qu’une classe class avec ses méthodes correspond à Z vu comme un anneau, i.e. comme un ensemble

description de Z est beaucoup plus utile que la première !

Une classe est une liste de champs et de méthodes déclarée par : #ifndef REF_DE_LA_CLASSE

2 #define REF_DE_LA_CLASSE

class NOM_DE_LA_CLASSE {

4 private:// ou protected selon les besoins type1 champ1; 6 type2 champ2; ... 8 typeN champN; //prototype de la methode 1: 10 t1 nom_de_la_methode_1 (arguments_1) ; // prototype de la methode 2: ... 12 t2 nom_de_la_methode_2 (arguments_2) ; ... 14 public: typeA champA; 16 ... tA nom_de_la_methode_A (arguments_A) ;

18 ... // autres champs et autres methodes

//Constructeurs: 20 NOM_DE_LA_CLASSE(arguments1); //constructeur 1 ... 22 NOM_DE_LA_CLASSE(argumentsM); //constructeur M //Destructeurs: 24 ~NOM_DE_LA_CLASSE() ; //destructeur

}; //ATTENTION, le point-virgule final est absolument nécessaire !!!

26 #endif

Cette définition doit être écrite dans un en-tête .hpp qui doit être inclus dans tous les fichiers qui utilisent des objets de cette classe. Attention, la déclaration de la classe doit se terminer absolument par un point-virgule !

La partie public. La définition d’un objet de type NOM_DE_LA_CLASSE se fait comme toutes les déclarations de variables par :

NOM_DE_LA_CLASSE nom(argumentsK);

où la liste des arguments argumentsK doit correspondre à l’un des constructeurs de la classe. Comme pour les types usuels, à l’issue de cette déclaration, une zone de la mémoire est allouée à la variable nom : cette zone correspond à tous les champs publics et privés champ1 , etc., champA , etc. Si le constructeur numéro K contient des new, de la mémoire supplémentaire est allouée. L’initialisation de toutes ces zones mémoires se fait selon les instructions écrites dans les constructeurs ; si rien n’est écrit à ce sujet, les valeurs d’initialisation sont imprévisibles.

Une fois cette variable nom déclarée, le programmeur a le droit d’accéder à tous les champs étiquetés public par la syntaxe :

5.1. GÉNÉRALITÉS SUR LES CLASSES 87

nom.champ

comme pour les struct. Le programmeur a également le droit d’appeler toutes les méthodes étiquetées public par la syntaxe :

nom.nom_de_la_methode_K(arguments_K)

où les arguments respectent les types donnés dans le prototype de la méthode. Cela produit alors une valeur de type tK .

Seule la partie public intéresse les utilisateurs de la classe.

La partie private. Les champs et méthodes étiquetés private ne sont utilisables qu’à l’intérieur du code des méthodes publiques ou privées (ainsi que par les fonctions externes déclarées friend, cf. plus bas) et nulle par ailleurs. Cela permet d’éviter qu’un utilisateur de la classe qui ne connaît pas son fonctionnement interne n’écrive des instructions dangereuses. La partie private n’intéresse donc que les concepteurs de la classe et non les utilisateurs.

Description des méthodes de la classe. Seuls les prototypes des méthodes figurent dans la classe. Le code des méthodes est écrit dans un fichier d’extension .cpp qui doit inclure le .hpp de définition de la classe et qui doit être compilé séparément.

Dans ce fichier .cpp , il n’y a plus de distinctions entre public et private et l’ordre d’écriture des codes n’importe pas. Normalement, un utilisateur de la classe n’a jamais à ouvrir ce fichier ; d’ailleurs, il arrive fréquemment que seule la version compilée soit fournie à l’utilisateur.

La définition d’une méthode se fait comme la définition d’une fonction, à ceci près qu’il faut spécifier la classe à laquelle elle appartient avec l’opérateur de résolution :: comme ceci :

t1 NOM_DE_CLASSE::nom_de_la_methode_1(arguments1) {

2 ...

//instructions de la methode;

4 return ... ; // un objet de type t1 }

Lors de l’écriture du code d’une méthode, il faut toujours garder à l’esprit qu’elle contient un argument de plus que ceux écrits dans son prototype. En effet, elle est toujours utilisée associée à un objet par var.nom_de_la_methode(args) et il faut considérer l’objet d’appel comme un argument supplémentaire fantôme. On accède à son adresse par le pointeur this ou en faisant mention du champ ou de la méthode sans préfixe.

Par exemple, si nous reprenons le code de la figure5.2, la méthode trace() accède au champ coeffs directement : par convention, à chaque appel de trace() sous la forme var.trace() , c’est le champ coeffs de l’objet var qui est utilisé. Pour lever le doute, nous aurions pu écrire de manière complètement équivalente à la ligne 17 :

t+= this->coeffs[i*n+i];

Qualificatif const. Lorsqu’une méthode d’une classe ne modifie pas les champs de l’objet sur lequel elle est appelée, il faut l’étiqueter const. Ce mot-clef doit être placé à la fin du prototype à l’intérieur de la classe ainsi que lors de la définition de la méthode. Il n’est appuyé à aucun argument de la liste d’arguments et par convention s’applique à l’objet d’appel pointé par this.

Son usage est obligatoire. En effet, une méthode étiquetée const (ou une fonction extérieure à la classe dont un argument est un objet de la classe et est marqué const) ne peut faire intervenir bien évidemment que des méthodes étiquetées const. Oublier de qualifier une méthode const restreint donc son utilisation. Or, de nombreux opérateurs déjà présents dans des bibliothèques comportent des const, comme par exemple + et

<<. Oublier tous les const dans une classe empêche donc d’utiliser ces opérateurs ! Qualificatif static devant un camp privé. Il est possible d’ajouter le mot-clef

static devant un champ privé dans la définition d’une classe. Alors, ce champ sera commun à tous les objets de la classe. Cela peut être utile pour éviter de stocker une même information, parfois volumineuse, dans toutes les instances d’une classe ou bien pour étudier des caractéristiques globables d’une classe, par exemple connaître en temps réel le nombre d’objets existants de la classe. Il faut alors faire attention aux constructeurs et destructeurs comme expliqué ci-dessous.

L’initialisation d’une telle variable doit se faire une seule fois dans le code à travers la syntaxe

TYPE NOM_CLASSE::NOM_VARIABLE = VALEUR;

De plus, cette variable n’étant plus liée nécessairement à un objet de la classe, elle peut être utilisée librement avec la syntaxeNOM_CLASSE::NOM_VARIABLE , indépendamment de toute déclaration d’objets de la classe.

5.2

Présentation des différentes méthodes

Documents relatifs