Vous êtes sur la page 1sur 104

PROGRAMMATION ORIENTÉE

OBJET EN C++

Pr. J. Alami Chentoufi SMI 5


Département d’Informatique
Faculté des Sciences- Kénitra Année Universitaire 2014- 2015
PLAN DU COURS

Partie I. Paradigmes de Programmation

Partie II. Principes de la programmation orientée objet

Partie III. Eléments préalables du Langage C++

Partie IV. Programmation orientée objet en C++

2
« Partie I. Paradigmes de Programmation »
PARTIE I. PARADIGMES DE PROGRAMMATION

Définition:

❖ Paradigme
• Une représentation du monde, une manière de voir les choses
• Un ensemble de théories, standards et méthodes pour
représenter et organiser la connaissance

❖ Paradigme de programmation
• Un outil de pensée qui oriente la façon d’analyser, de

concevoir et de coder un programme

4
PARTIE I. PARADIGMES DE PROGRAMMATION

Paradigmes principaux:

❖ Programmation impérative

❖ Programmation fonctionnelle

❖ Programmation logique

❖ Programmation orientée objet

Chaque paradigme a sa propre structure de contrôle

5
PARTIE I. PARADIGMES DE PROGRAMMATION

Paradigme Impératif/Procédural:
❖ Décrit les opérations en termes d’états du programme
et de séquences d’instructions exécutées par
l’ordinateur pour modifier l’état du programme.
Exemples: Fortran, Pascal, C.
Paradigme Fonctionnel:
❖ Considère le calcul en tant qu’évaluation de fonctions
mathématiques et rejette le changement d’état et la
mutation des données.

6
PARTIE I. PARADIGMES DE PROGRAMMATION

Paradigme Logique:
❖ Définit des règles de logique mathématique au lieu de
fournir une succession d’instructions (Ex: PROLOG).
Paradigme orienté objet:
❖ Consiste en la définition et l’assemblage de briques
logicielles appelées objets.

❖ Exemples : C++, Java, etc

7
PARTIE I. PARADIGMES DE PROGRAMMATION

Paradigme Procédural et Fonctionnel


❖ Un programme est composé de
plusieurs procédures (ou fonctions) : Données
• qui effectuent un traitement sur
des données (procédure)

• qui retournent une valeur après Traitement 1


leur invocation (fonction)

❖ Certains langages ne distinguent pas Traitement 1


procédures et fonctions.

❖ Exemples de langages procéduraux Traitement 1


ou fonctionnels : Fortran, Lisp, C, ...
8
PARTIE I. PARADIGMES DE PROGRAMMATION

Paradigme Orienté Objet :


❖ Un programme est composé de
plusieurs objets qui contiennent :
• des données ”internes”

• des traitements manipulant ces données 



internes ou d’autres données

❖ Les données d’un objet sont appelés


ses attributs et les traitements sont
ses méthodes (ou opérations).

9
« Partie II. Principes de la programmation
orientée objet »
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Qu'est ce qu’un Programme Objet 1


Orientée Objet POO ?

• Ensemble d'objets autonomes


et responsables qui s'entraident Objet 2
Objet 4
pour résoudre un problème
final en s'envoyant des
messages. Objet 3

11
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

La notion d’objet:
❖ Un objet = un concept, une idée ou une entité du monde physique

• Etudiant, voiture, personne, animal,compte bancaire, Point ...

❖ Dans un programme, un objet s’apparente à une variable

❖ Un objet est caractérisé par trois notions:

• Les attributs : données de l’objet / variables qu’il contient et


représentant son état

• Les méthodes (fonctions membres) : caractérisent son


comportement, l’ensemble des actions que l’objet peut réaliser,
accès/modification des données

• Une identité, qui permet de le distinguer de manière unique des


autres objets, indépendamment de son état
12
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

La notion de classe:
❖ Une classe = la structure d’un objet
• Elle définit son type

• Déclaration de l’ensemble des entités qui composeront un


objet

❖ Un objet est donc obtenu à partir d’une classe


• Un objet est une instance d’une classe (on parle
d’instanciation de classe)

❖ Une classe est composée de deux parties :

• Les attributs (données membres)

• Les méthodes (fonctions membres)


13
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Exemple de classe: Etudiant


CNE : int
❖ Définition d’une classe Etudiant: Nom: char []
Prenom : char[]
• définir un type Etudiant Moyenne: float
Notes : float[]
• regroupe les propriétés communues aux
personnes : caractéristiques (attributs) et Calcul_Moyenne() : void
comportement (méthodes) Modif_Note(int i): void

Exemple d’un objet:


Etudiant 1
❖ Instanciation d’un objet de type Etudiant CNE : 1239
Nom: ABC
• affectation d’une valeur à chaque attribut Prenom : DEF
Moyenne: 12.75
• possibilité d’agir, via les méthodes Notes : {10,

Calcul_Moyenne() : void
Modif_Note(int i): void
14
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Les principes fondamentaux de la POO:

❖ Abstraction
❖ Encapsulation
❖ Classe et objets
❖ Héritage
❖ Polymorphisme

15
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Abstraction des données:

❖ La structure interne des données est cachée à l’utilisateur qui


ne connaît d'elles que les procédures permettant de les traiter.

❖ L’objet est considéré comme une boîte noire que l'on manipule
en lui envoyant des messages.

16
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Encapsulation:
❖ Rassembler les données et méthodes au sein d’une structure:

• en cachant l’implémentation de l’objet

• en protégeant l’accès aux données—>utilisation d’un mécanisme


d’accès / modification

• augmente la sécurité d’une application

❖ permet de définir des niveaux de visibilité des éléments de la classe:

• Public

• protected

• private


17
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Héritage:
❖ permet la création d’une classe à partir d’une classe existante:
• La classe dérivée (fille) contient sous certaines conditions les attributs et
les méthodes de la classe mère (super-classe)
• Possibilité de réutiliser le code
• Plusieurs types d’héritage : public, protégé, ou privé

Forme_Geometrique Classe mère

Classe fille Cercle Rectangle

Carre
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Polymorphisme:

❖ Nom grec qui signifie qui peut prendre plusieurs formes.

❖ Le polymorphisme est relatif aux méthodes des objets.

❖ Trois types de polymorphisme :

✦ Le polymorphisme ad-hoc : surcharge (en anglais overloading)

✦ Le polymorphisme paramétrique : généricité (en anglais template)

✦ Le polymorphisme d'héritage : redéfinition (en anglais overriding).


19
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Le polymorphisme ad-hoc :
✤ Définir des méthodes de même nom dans des classes indépendantes.

✤ Permet d’avoir des fonctions de même nom, avec des fonctionnalités


similaires, dans des classes sans aucun rapport entre elles.

✤ Exemple: fonction afficher () pour la classe Etudiant, Enseignant, etc

20
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Le polymorphisme paramétrique :

✦ Possibilité de définir plusieurs fonctions de même nom mais


possédant des paramètres différents (en nombre et/ou en type).

✦ On appelle signature le nombre et le type (statique) des


arguments d’une fonction. C’est donc la signature d’une
méthode qui détermine laquelle sera appelée.

✦ Exemple la fonction somme:


int somme (int, int);

float somme (float, float);

21
PARTIE II. PRINCIPES DE LA PROGRAMMATION
ORIENTÉE OBJET

Polymorphisme d’héritage:

PersonneUniv

Afficher_Info()

Etudiant Enseignant Administrateur

Afficher_Info() Afficher_Info() Afficher_Info()

L’implémentation de la fonction Afficher_Info() est différente selon le type


de la personne universitaire
22
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
Fonctionnalités introduites par C++:
✦ Le type primitif bool ( les booléens) et le type string (les chaînes de
caractères)

✦ L’emplacement libre des déclarations

✦ Les flux standards d’entrée sortie

✦ Les références

✦ Le casting (typage forcé)

✦ Les valeurs par défaut des arguments des fonctions

✦ Les opérateurs new et delete pour la gestion dynamique de la mémoire

✦ La surcharge des noms de fonctions

✦ Les fonctions ‘inline’

23
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
Le type bool :
✦ Le type bool (pour booléen) comporte deux valeurs : false et true

✦ Le résultat d’une opération logique (&&, ||, et !) est de type booléen,

✦ Là où une condition est attendue on doit mettre une expression de type


booléen,

✦ Il est déconseillé de prendre les entiers pour des booléens et


réciproquement.

✦ Exemple :

bool test = true;

while (test == true){….}

24
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

L’emplacement libre des déclarations :


✦ Possibilité de déclarer des variables n'importe où dans une fonction ou un
bloc

✦ La déclaration d’une variable est faite jusqu’à l’endroit du programme où


l’on dispose d’assez d’éléments pour l’initialiser.

✦ Exemple:

Langage C: Langage C++:

int i, j,k; …….


…….
 ……..

for(i =0, j=1; ; ) for(int i = 0, j=1, k; ; )
k= …..
 k= …..
…….
 …..
} }

25
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Les flux standards d’entrée sortie :


✤ La bibliothèque iostream contient les déclarations relatives aux flux d’entrée-
sortie (cin, cout, …), ainsi qu’aux opérateurs (fonctions)particuliers << et >>.

✤ cin: flux standard d’entrée, qui est habituellement associé au clavier;

✤ >>: opérateur d’extraction ou de lecture d’un flux d’entrée: cin.

✤ cout: flux standard de sortie, qui est habituellement associé à l’écran.

✤ <<: opérateur d’injection ou d’écriture dans un flux de sortie: cout

✤ Syntaxe:

cin>>nom_variable1>>nom_variable2>>…

cout <<expression à écrire;

26
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Programme en C++ utilisant les flux dE/S:

#include <iostream.h>
int main( ) {
unsigned int N;
float X,Puiss =1.0;
cout << "donnez X et N :";
cin >> X >> N;
for(int i = 0; i < N; i++)
Puiss = Puiss * X;
cout << X <<" ^ "<< N << "=" << Puiss <<endl;
return 0;
}

27
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
Les références:
✦ Une référence est un moyen d’associer un nouveau Exemple:
nom à une variable (ou objet) existant déjà.
int A=2;
✦ Introduites en C++ pour faciliter le passage des int &refA = A; //initialisatoin obligatoire!
paramètres à une fonction : passage par référence
refA++;
✦ Syntaxe de déclaration d’une référence:
// maintenant A=3
type & Nom_de_la_variable = valeur;
/* déréférence impossible ==> modification
✦ Deux règles à respecter pour les références : de la valeur contenue: */
1. une référence doit obligatoirement être
initialisée lors de sa déclaration int B=5;

2. une référence ne peut pas être déréférencée refA=B; //signifieA=5!!!!


d’une variable à une autre.
refA++;   //A=6, B=5, et refA=6

Une valeur de type référence est une adresse mais, une fois initialisée, toute opération
effectuée sur la référence agit sur l’objet référencé
28
et non sur l’adresse.
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Passage des paramètres par référence:


✦L’utilisation des références permet de donner aux fonctions des paramètres
modifiables, sans utiliser explicitement les pointeurs

✦Exemple:
void permuter(int & a, int & b) {
int temp = a;
a = b;
b = temp; }
L’appel de cette fonction se fait de la façon suivante:
int main ( ){
int A, B;
cin<< A<<B;
permuter (A, B);
return 0; }

29
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Fonctions renvoyant une référence :


✦ Possible d’écrire des fonctions qui renvoient comme résultat une référence.

✦ Exemple: la fonction NoteInfo permet de simuler un tableau indexé par des


chaînes de caractères et qui retourne une référence à la note associée à un nom
d’étudiant :
char *noms[N];
int note_Info[N];
int & NoteInfo(char *nom) {
for (int i = 0; i < N; i++)
if (strcmp(nom, noms[i]) == 0)
return notes_Info[i];
}

Exemple d’appel: NoteInfo ("nom_etudiant") = 16;

30
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Références sur des données constantes :

✦ Dans une fonction il est parfois souhaitable d’utiliser des arguments


références sans pouvoir modifier la valeur des variables ==> références
sur des données constantes (qualifieur const)
✦ Exemple:

void uneFonction(const Type & arg) {


...
//ici arg n’est pas une recopie de l’argument effectif (puisque référence)
//mais il ne peut pas être modifié par la fonction (puisque const)


}

31
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Références ou pointeurs?
✦ Les références ne peuvent pas remplacer les pointeurs.

✦ Les références ne peuvent pas faire référence à un tableau


d’éléments.

✦ Les références ne peuvent pas faire référence à une nouvelle variable


une fois qu’elles ont été initialisées.

✦ Il est recommandé de n’utiliser les références que pour le passage de


paramètres aux fonctions.

32
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

L’opérateur de cast
✦ Quatre types de conversion possibles et réalisables en C++ :

1. static_cast : pour la conversion statique de types;

2. reinterpret_cast : pour la ré-interprétation des données d'un type vers


un autre;

3. const_cast : pour la "conversion" d'un pointeur (ou référence) constant(e)


vers un pointeur (ou référence) non-constant(e);

4. dynamic_cast : pour la conversion de types dynamique.

33
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

La conversion statique: Static_cast:


✦ Permet de forcer les types de variables de même famille (on parle de famille de
pointeurs, de types primitifs, de références, etc,.)

✦ Syntaxe:

static_cast<type>(expression) en Langage C : (type)(expression)

Exemples:
double d= 2.34;
float f =1.2;
int a= 1, b= 5;
d = static_cast<double>(f);
a= static_cast<int> (d);
float q = static_cast <float> (a)/b;// équivalent en C à q = (float) a/b;

34
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

La ré-interprétation des données : reinterpret_cast


✦ L’opérateur de conversion le plus dangereux:

• convertit n’importe quel type pointé en une autre, même lorsque ceux-ci
n’ont aucun rapport. ex: de int * —> float *

• convertit un type pointé en sa représentation intégrale et vice et versa.


Exemple : int* vers int.

Exemple :
int a = 5;
//conversion d’un double vers double *
double* b= reinterpret_cast<double*>(&a); //*b dépend du compilateur
//conversion d’un double * vers int *
int * c = reinterpret_cast<int*>(b); // *c vaudra a, c’est à dire 5.


35
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

La conversion des pointeurs sur constante:


const_cast:

✦ Permet de supprimer l’attribut constant d’une référence ou d’un type pointé


(const type* —> type*)

✦ Exemple:

char* buf = (char *) malloc(16);


// L’ajout de l’attribut const ne nécessite pas de cast, Il est implicite

const char * cbuf = buf;
// Le retrait de l’attribut const nécessite const_cast<>.
char* buf2 = const_cast<char*>(cbuf);

36
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

La conversion dynamique : dynamic_cast


✤ Peut être utilisé seulement pour les pointeurs et les références sur
des objets de type classe, notamment quand il s’agit de classes de
base et dérivée.

37
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
Les arguments par défaut d’une fonction:

✦ En C, l’appel d’une fonction doit contenir


void f(int arg1, int arg2 = 12) ;
exactement le même nombre et type
main () {
d’arguments que dans la déclaration de la int n = 10 ; int p = 20 ;
fonction. // Appel de f avec 2 valeurs
f(n, p) ;
✦ En C++, il est possible d’omettre quelques /* Appel de f avec une valeur, la
arguments lors de l’appel d’une fonction, en deuxième sera la valeur par
utilisant les arguments par défaut. défaut*/
f(n) ;
✦ Les arguments par défaut doivent être les }
derniers de la liste des arguments. // Définition de la fonction f
void f(int a, int b) {
✦ Les valeurs par défaut doivent être fixées cout << " 1er arg : "<< a ;
dans la déclaration ou dans la définition de la cout <<" et 2eme arg : " << b;
}
fonction.

38
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
Les opérateurs de gestion dynamique de la mémoire: new
et delete
L’opérateur new L’opérateur delete
✦L’opérateur new remplace la fonction ✦L’opérateur delete remplace la
malloc (allocation dynamique de la fonction free (libération de la
mémoire). mémoire).
✦ Les objets créés à l’aide de new ✦ Les objets libérés à l’aide de delete
sont initialisés à l’aide des sont détruits à l’aide des
constructeurs. destructeurs.
✦ new renvoie une valeur de type ✦ Pour libérer la mémoire occupée par
pointeur sur un type: type * . un seul objet obj: delete obj;
✦ Pour allouer un seul objet: new ✦Pour libérer l’espace mémoire occupé
type par un tableau d’objets : delete []
✦ Pour allouer un tableau de n objets : obj
new type[n]
39
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++

Les opérateurs new et delete


Exemple:

int*ad=new int;
int *tab = new int[n]; // Tableau créé dynamiquement de n int
char (*M)[20]; // pointeur de tableaux de 20 char ...

//acquisition de la valeur de n
……
M = new char[n][20]; // allocation d’un tableau de n tableaux de 20 char
// Traitement
…..
//Libération de l’espace mémoire alloué par new
delete ad;
delete []tab;
delete []M;

40
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
La surcharge des fonctions:
✦ Des fonctions différentes portant le même nom mais elles ont des
signatures différentes.

✦ Lors de l’appel, le type et le nombre d’arguments fournis permettent de


choisir, sans ambiguité, la fonction requise.

✦ Le type du résultat rendu par la fonction ne fait pas partie de la signature.

✦ Ilest impossible de donner le même nom à deux fonctions qui ne diffèrent


que par le type du résultat.

Exemple :
int puissance(int x, int n) {
calcul de xn avec x et n entiers }
double puissance(double x, int n) {
calcul de xn avec x flottant et n entier }
41
PARTIE III. ELÉMENTS PRÉALABLES DU
LANGAGE C++
Les fonctions inline:

✦ A l’appel d’une fonction, la machine cesse d’exécuter séquentiellement


les instructions en cours; les arguments de l’appel sont disposés sur la
pile d’exécution, et l’exécution continue ailleurs, là où se trouve le code
de la fonction.
✦ Par contre, lors d’un appel d’une fonction inline, le compilateur
remplace l’appel par le corps de celle-ci, en mettant les arguments
effectifs à la place des arguments formels.
✦ La portée d’une fonction ‘inline’ est réduite au fichier où la fonction est
définie (en général dans un fichier d’entête .h).
✦ Exemple de déclaration d’une fonction inline:
inline int carre(int x) {
return x*x ; }

42
“Partie IV.Programmation orientée objet
en C++”

43
VOCABULAIRE OBJET (1/3)

Classe: Avantages:
✤ La description d'une famille ✤ Simplifie l'utilisation des objets,
d'objets ayant même ✤ Rapproche les données et leur
structure et même traitement
comportement. ✤ Simplifie la maintenance
✤ Permet l'encapsulation :
✤ La classe regroupe un
possibilité de ne montrer de l'objet
ensemble d'attributs ou
que ce qui est nécessaire à son
membres, répartis en un
utilisation.
ensemble de données et un ✤ Permet de masquer
ensemble de méthodes.
l'implémentation

44
VOCABULAIRE OBJET (2/3)

Objet :
✦ un élément de la classe ou une instance de la classe
✦ obtenu par instanciation
Attribut ou membre :
✦ Une propriété ou état de l’objet
✦ L’état d’un objet est l’ensemble des valeurs de ses attributs
✦ Les valeurs des données membres peuvent différer d'une
instance à l'autre (sauf pour des données statiques de
classe).
Méthode ou fonction membre :
✦ Une fonction qui s’applique sur une instance (ou objet) de
la classe
✦ Les méthodes sont les mêmes pour toutes les instances
d'une classe. On distingue entre méthodes d'objet
(d'instance) et méthodes de classe.
45
VOCABULAIRE OBJET (3/3)

Encapsulation des données :

✤Masquage, dans l’implémentation de la classe, tous les


attributs.
✤Ces attributs sont accessibles par une méthode de lecture
et une méthode d’écriture situées dans l’interface de la
classe.
✤ Il existe trois mots-clés: ‘private’, ‘public’ et ‘protected'

46
DÉCLARATION D’UNE CLASSE (1/2)

✤Pour déclarer une classe il faut utiliser le mot clé ‘class' et il faut
préciser les quatre éléments suivants :
✤ Les variables, appelées attributs (ou variables membres),
✤ Les fonctions, appelées méthodes (ou fonctions membres).
✤ Les niveaux de protection (public, private et protected)qui
conditionneront l'accès aux données et fonctions membres ;
✤ Le nom de la classe qui servira de spécificateur de type.

✤ La syntaxe de déclaration d’une classe :


class nom_de_classe {
private :
//espace de définition des membres privés
protected :
//espace de définition des membres protégés
public :
//espace de définition des membres publics
};

47
DÉCLARATION D’UNE CLASSE (2/2)

✤ Un objet Point est défini par: class Point { Point.h


• 2 attributs publics: x et y
• 2 fonctions membres // Déclaration des attributs : x et y
public :
publiques: initialise_Point, int x ;
affiche_Point int y ;
// Déclaration des fonctions membres
✤ La déclaration d’une classe doit void initialise_Point(int , int );
void affiche_Point() ;
se faire dans un fichier
};
d’entête (.h)

48
DÉFINITION DES FONCTIONS MEMBRES (1/2)

✤ Deux façons pour définir des fonctions membres d’une classe:


1. en définissant la fonction à l’intérieur de la classe en une
opération et ceci se fait dans le fichier d’entête (.h)
2. ou en la définissant à l’extérieur dans un autre fichier source
dont l’extension est .cpp ( portant le même nom du fichier header
dans lequel la classe est définie) ==> plus préférable
✤ L' opérateur de portée :: indique la classe à laquelle appartient la
méthode (dans le cas où la fonction est définie à l’extérieur de la
classe).
✤ Syntaxe de l’opérateur de portée :
type_resultat nom_classe :: nom_fonction( ….);

49
DÉFINITION DES FONCTIONS MEMBRES (2/2)

#include <iostream.h> Point.cpp


#include “Point.h”
void Point :: initialise_Point(int a, int b) {
x = a;
y = b;
}
void Point :: affiche_Point( ) {
cout<< " ( " <<x<< " , " <<y<< " ) "<< endl;
}

50
ACCÈS AUX MEMBRES D’UN OBJET (1/)

✤L’accès aux membres des objets est similaire à l’accès aux


membres des structures.
✤A partir de la classe définie Point on peut déclarer des objets de
cette classe.
✤ Deux façons de créer des objets (ou instancier une classe) :
1. de façon statique
2. de façon dynamique

51
ACCÈS AUX MEMBRES D’UN OBJET (2/)
CRÉATION STATIQUE D’OBJETS
✤ Syntaxe :
NomClasse NomObjet;
✤ L’accès à partir d’un objet à un attribut ou une méthode de la classe
instanciée se fait grâce à l’opérateur ‘ . ‘

#include “Point.h" main.cpp


int main( )

{

Point A; // on déclare un objet de type Point A
A.x = 1; // Accéder au membre x de l’objet point A et l’initialiser à 1
A.y = 2; // Accéder au membre y de l’objet point A et l’initialiser à 2
//Appel de la fonction initialise_Point de l’objet Point
A.initialise_Point(10, 20);
// Appel de la fonction affiche_Point de l’objet Point A
A.affiche_Point();
return 0; }
52
ACCÈS AUX MEMBRES D’UN OBJET (2/)
CRÉATION DYNAMIQUE D’OBJETS
✤ Syntaxe :
NomClasse *NomObjet = new NomClasse;
✤ L’accès à partir d’un objet créé dynamiquement à un attribut ou une
méthode de la classe instanciée se fait grâce à l’opérateur ‘ -> ‘

#include “Point.h" main.cpp


int main( )

{

Point *pt; // on déclare un pointeur sur un objet de type Point A
pt = new Point; // Allocation dynamique d’un point
pt->x = 1; // Accéder au membre x de l’objet pointé par pt
pt->y = 2; // Accéder au membre y de l’objet pointé par pt
// Appel de la fonction affiche_Point de l’objet pointé par pt
pt->affiche_Point();
delete (pt); // Libération de la mémoire occupée par pt
return 0; }
53
ACCÈS AUX MEMBRES D’UN OBJET (2/)
AUTORÉFÉRENCE: THIS

✤ Un objet peut s’auto référencer en utilisant this.

✤ Toute classe en C++ possède un membre donnée privé nommé this.

✤ this est utilisable uniquement au sein d’une fonction membre, désigne


un pointeur sur l’objet l’ayant appelé.

✤ Exemple:

bool Point::test_Egalite_Point(Point P){


return this->x == P.x && this->y == P.y;
//ou bien return x ==P.x && y==P.y
}

54
ENCAPSULATION ET DROITS D’ACCÈS AUX
MEMBRES D’UNE CLASSE

Trois modes d’accès :

1. public : plus bas niveau de restriction d’accès aux données. Toutes


les fonctions membres (de n’importe quelle classe) peuvent accéder
aux données ou aux méthodes déclarés public.

2. protected : l’accès aux variables et fonctions protégées est limité


aux fonctions membres de la classe et aux fonctions des classes filles
(classes héritant de la classe mère).

3. private : le plus haut niveau de restriction d’accès. Seules les


méthodes de la classe elle-même peuvent accéder aux membres
privés (Mode par défaut).

55
MÉTHODES PARTICULIÈRES D’UNE CLASSE: LES
CONSTRUCTEURS

✤ Permettent d’initialiser l’objet lors de sa création


• copie des arguments vers les données membres
• initialisation de variables dynamiques à la création de l’objet
✤ Sont appelés de manière automatique à la création de l’objet
✤ Peuvent être surchargés—>On peut en définir plusieurs de même
nom mais acceptant des arguments différents
✤ Possèdent le même nom que la classe
✤ Ne possèdent pas de type de retour

56
MÉTHODES PARTICULIÈRES D’UNE CLASSE: LES
CONSTRUCTEURS
class Point { Point.h
private :
double x ;
double y ;
// Déclaration des constructeurs de la classe
public:
Point(double abs , double ord ); // valeurs par défaut x=0 et y=0
Point (double abs);
Point ( );
};
//Définition des constructeurs
Point :: Point(double abs, double ord) : x(abs), y(ord){ }
Point :: Point (double abs) : x(abs), y(0){ }
Point :: Point ( ) : x(0), y(0){ }

Point a(3, 4); //Création d’un objet a par un appel explicite au constructeur
Point p (7);
Point *pt;
pt = new Point(1, 2);
57
MÉTHODES PARTICULIÈRES D’UNE CLASSE: LES
CONSTRUCTEURS PAR DÉFAUT

Un constructeur qui peut être appelé sans paramètres :


Point x;
Point *p = new Point; // équivaut à : p = new Point()
Point *q = new Point[10]; // produit 10 appels de Point()

58
MÉTHODES PARTICULIÈRES D’UNE CLASSE: LES
CONSTRUCTEURS DE COPIE (CLONAGE)

✤ Le clonage c’est créer un objet à partir d’un objet déjà créé de la


même classe.
✤ Copie une à une les valeurs des champs de l’objet à copier dans les
champs de l’objet à instancier.
✤ Utilisé notamment, lorsqu’une classe contient un champ dynamique
(pointeur).
✤ Syntaxe du constructeur de copie:

Nom_Classe (Nom_Classe &obj);

59
MÉTHODES PARTICULIÈRES D’UNE CLASSE: LES
CONSTRUCTEURS DE COPIE (CLONAGE)
class Point { Point.h
private :
double x , y ;
char *label; // chaîne de caractères contenant le nom du point
public:
//Déclaration du constructeur, valeurs par défaut x=0 et y=0 et label = " "
Point(double abs , double ord, char *lab=" " );
Point(Point &pt) ; // Déclaration du constructeur de copie
};
//Définition des constructeurs
Point :: Point(double abs, double ord, char *lab): x(abs), y(ord){
label = new char[strlen(lab) + 1];
strcpy(label, lab); }
Point :: Point (Point &ref){
x = ref.x;
y = ref.y;
label=new char[strlen(ref.label)+1];
strcpy(label, ref.label); }

60
MÉTHODES PARTICULIÈRES D’UNE CLASSE: LES
DESTRUCTEURS

✤ Il est unique (ne peut pas être surdéfini)

✤ Appelé automatiquement lors de la destruction de l’objet

✤ Sert généralement à éliminer les variables dynamiques de l’objet


(créées en général par le constructeur)

✤ Il a pour nom le nom de la classe précédé du symbole ~

✤ Il n’a pas de type de retour

✤ Il ne possède pas d’arguments

✤ exemple: ~Point();

61
MÉTHODES PARTICULIÈRES D’UNE CLASSE:
LES DESTRUCTEURS

class Point { Point.h


private:
double x, y;
char *label; // champ dynamique
public:
Point(double a=0,double b=0);
~Point(); // destructeur };
Point::Point(double a, double b, char *S): x(a), y(b) {
label = new char[strlen(S)+1];
strcpy(label, S);
}
Point::~Point( ){
delete [ ]label;
}

62
MEMBRES CONSTANTS : DONNÉES MEMBRES
CONSTANTES
✦ Le mot clé ‘const' peut être ajouté à la déclaration d’une donnée
✦ Une constante ne peut pas être modifiée
✦ Elle doit être initialisée soit:
1. Lors de sa définition ( exemple: const double Pi = = 3.14159;)
2. Dans le constructeur.
class Etudiant{ Point.h
private:
//pas possible d’initialiser CNE, car chaque étudiant possède son propre CNE
const int CNE; char *nom, *prenom;
public:
Etudiant ( char *N, char *P, int code); //Constructeur
};
//Définition du constructeur: initialisation des données nom, prénom et CNE
Etudiant :: Etudiant (char *N, char *P, int code) : CNE(code) {
nom= new char[strlen(N)+1]; strcpy(nom, N);
prenom= new char[strlen(P)+1]; strcpy(prenom, P); }
63
MEMBRES CONSTANTS : MÉTHODES CONSTANTES

✦ Sont des méthodes de « lecture seule »: ne modifient pas l’objet —>


aucune modification de la valeur de ses attributs.
✦ Possèdent le mot-clé const à la fin de leur prototype et de leur
déclaration
class Point { Point.h
private:
double x;
double y;
char *label; // champ dynamique
public:
Point(double a=0,double b=0);
void setPoint(double x, double y, char *label); // modifie la valeur des attributs
double getAbs( ) const; //fonction qui retourne la valeur de x
double getOrd( ) const; //fonction qui retourne la valeur de y
};
Point::setPoint ( double x, double y, char *label){
this->x = x; this->y =y;
this->label = new char[strlen(label)+1]; strcpy(this->label, label); }
double Point::getAbs( ) const { return x; }
double Point :: getOrd() const {return y; }

64
POINTEURS ET OBJETS CONSTANTS

Pointeur sur un objet constant: Pointeur constant sur un objet:


✦ Modifications sur l'objet constant ✦ Il faut initialiser un pointeur
sont interdites. constant lors de sa définition.
✦ Possibilité de changer la valeur ✦ Impossibilité de changer la valeur
du pointeur. du pointeur.
// Déclaration d'un double constant
const double pi = 3.14159; ✦ Possibilité de changer la valeur
/*Déclaration d’un Pointeur ptr1(non
de l’objet pointé
// Déclaration de deux double
constant)sur un double constant initialisé à double x = 0.0, y = 0.0;
l’adresse de pi*/ /* Déclaration d'un pointeur constant
const double * ptr1 =&pi; initialisé avec l'adresse de x*/
*ptr1 = 12; // Erreur double *const ptr2 = &x;
// Déclaration d'un autre double constant *ptr2 = 1.5; /* OK (modification de
const double e = 2.71828; l'objet pointé, x prend la valeur 1.5)*/
/* OK (modification de la valeur du ptr2 = &y; /* Erreur (tentative de
pointeur) */ modification de la valeur du pointeur)*/

65
MEMBRES STATIQUES

✤ Membres partagés par tous les objets de la classe.


✤ Non statiques : variables et méthodes d’instances.
✤ Statiques : variables et méthodes de classe.
✤ Il n’en existe qu’un seul exemplaire par classe.
✤ Il faut créer et initialiser la donnée membre statique (ce qui n’est
pas fait par le constructeur).
✤ Il faut initialiser une donnée statique dans l'espace global, c'est-à-
dire en dehors de toute classe ou fonction

66
MEMBRES STATIQUES

class Point { Point.h


int x, y;
public:
static int nbrPoints;
Point(int a, int b);
};

int Point::nbrPoints = 0; //On initialise nbrPoints à 0 Point.cpp


Point::Point(int a, int b){
Point::x = a;
Point::y =b;
//Quand on crée un objet Point, on incréments de 1 la valeur de nbrPoints
nbrPoints++;
}

67
MÉTHODES STATIQUES

✤ Des fonctions appartenant à la classe mais pas aux objets instanciés,


✤ Elles n'ont pas accès aux attributs non statiques de la classe,
✤ Elle ne dispose pas du pointeur this,
✤ Elles ne peuvent référencer que les fonctions et les membres statiques de leur classe.

class Point { Point.h


int x, y;
static int nbrPoints;
public:
Point(int a, int b);
static int getNbrPoints ( ); };

#include "Point.h" Point.cpp


int Point::nbrPoints = 0; //On initialise nbrPoints à 0
Point::Point(int a, int b){
Point::x = a; Point::y =b;
//Quand on crée un objet Point, on incréments de 1 la valeur de nbrPoints
nbrPoints++;}
int Point:: getNbrPoints(){
return Point::nbrPoints; }
68
FONCTIONS AMIES

✤ Une fonction amie d’une classe est une fonction qui, sans être membre de
cette classe, a le droit d’accéder à tous ses membres, aussi bien publics que
privés.
✤ Une fonction amie doit être déclarée ou définie dans la classe qui accorde
le droit d’accès
✤ Pour déclarer une fonction amie on utilise le mot clé ‘friend'

class Point { Point.h


int x, y;
friend void afficherPoint ( const Point &a);
public:
Point(int = 0, int = 0);
int getX() const { return x;}
int getY() const { return y;}
};

✤ La définition de la fonction amie se fait dans un autre fichier :


void afficherPoint(const Point &p) {
cout<<p.getX()<<endl<<p.getY();
}
69
SURCHARGE DES OPÉRATEURS

✤ La surcharge d'opérateur permet de donner aux opérateurs C/C++ un


comportement spécifique quand ils sont appliqués à des types
spécifiques (des classes).
✤ Les opérateurs surchargés remplacent avantageusement les appels de
fonction.
✤ La surcharge d'un opérateur est réalisée à l'aide d’une fonction
spécifique (fonction membre ou non) en utilisant le mot clé operator
✤ Le prototype de surcharge d’opérateur avec une fonction membre:
NomClasse operator SymboleOpérateur( NomClasse &
operande);
✤ Tous les opérateurs de C++ peuvent être surchargés sauf : « . »,
« : :», « ? », « : » et « sizeof ».

70
SURCHARGE DES OPÉRATEURS PAR UNE FONCTION
MEMBRE

class Point { Point.h


int x, y;
public:
Point(int = 0, int = 0);
int getX( ) const ;
int getY( ) const; #include “Point.h”
Point operator+(Point &) ; int main() {
}; Point p1(1,2), p2(2,3), r;
r = p1 + p2;
/*équivaut à :r =p1.operator(p2);*/
Point Point::operator+ (Point &a){ }
Point.cpp
Point b(x+ a.x,y +a.y);
return b;}
int Point ::getX( ) const{
return x; }
int Point::getY( ) const{
return y;
}

71
SURCHARGE DES OPÉRATEURS PAR UNE FONCTION
NON MEMBRE

✤ La fonction operator doit avoir un nombre de paramètres égal à la


pluralité de l’opérateur.

✤ Exemple :

// surcharge de + par une fonction non membre


Point operator+(const Point p, const Point q) {
return Point(p.getX() + q.getX(), p.getY() + q.getY()); }
//exemple d’utilisation
Point a(1,2);
Point b(2,3);
Point c = operator +(a, b); // ou bien Point c = a+b;

72
SURCHARGE DES OPÉRATEURS PAR UNE FONCTION
AMIE

✤ Dans le cas où la classe Point ne possède pas les accesseurs publics getX() et
getY(), on doit surcharger l’opérateur d’addition par une fonction amie.
✤ Exemple:
class Point {
int x, y;
public:

Point(int = 0, int = 0);

friend Point operator+(const Point &, const Point &);
};
// définition de la fonction amie dans un autre fichier
Point operator+(const Point &p, const Point &q) {
return Point(p.x + q.x, p.y + q.y);
}
✤ Un exemple d’utilisation de la classe Point:
Point p1, p2, r;
r = p1 + p2; //équivaut à : r = operator+(p1, p2);
r = p1+p2+r;

73
LA CLASSE STRING

✤ La classe string de C++ facilite la manipulation de chaînes de caractères.


✤ Pour employer la classe string, inclure le fichier en-tête string:
#include <string>
✤ L'implémentation de la classe string est complexe, et basée sur plusieurs
autres classes. Nous décrivons ses possibilités comme si elle était
implémentée directement.
Constructeurs:
✤ string() constructeur par défaut, initialise une chaîne vide.
✤ string(const char* c) construit une chaîne en l'initialisant avec la chaîne C.
✤ string(const string& a) constructeur par recopie, initialisé avec une copie de
a.
✤ string c; // vide
✤ string a = “ “;

74
OPÉRATEURS SUR STRING

✤ "+" pour la concaténation:


string a = "rouge", b("bleu"); string c = a + " " + b;

cout << c << endl;

✤ "+=" de concaténation incrémentale:


string a = "rouge"; a += " bleu";

✤ les 6 opérateurs de comparaison et notamment == pour la comparaison de chaînes:


string a = "rouge"; cout ("bleu" > a) << endl;
Aussi:
string x; //Chaine vide

string y = ""; //Chaine contenant mot vide cout<< x.size() << y.size() << (x==y)
<< endl;

75
MÉTHODES DE STRING

✤ replace(int d, int n, string b): remplace dans la chaîne appelante n caractères à


partir de la position d par la chaîne b.
string a = “Bonjour tout le monde", b = “à tous";
a.replace(8,13, b); donne “Bonjour à tous”.
✤ compare(const string& b) : retourne un entier négatif, nul, positif si la chaîne appelante
est inférieure, égale, supérieure à b.
string a = “Bonjour tout le monde", b = “Hello";
a.compare(b);
✤ int copy(char *t, int n, int d = 0): copie dans la chaîne existante t au plus n caractères à
partir de la position d.
string s = “test de copie"; char txt[20];

s.copy(txt, 4, 8);
t —> de copie
✤ const char* c_str() : conversion d’un string en une chaîne de caractères, copie les
caractères dans une chaîne constante, terminée par le caractère nul.
76
L’HÉRITAGE

✤ L’héritage correspond à une extension de l’objet (spécialisation).


✤ L’héritage peut être simple ou multiple.
✤ L’héritage correspond à une relation “est un”.
✤ La classe dérivée contient les attributs et les méthodes de sa classe de
base.
✤ On peut définir de nouveaux attributs et de nouvelles méthodes pour la
classe dérivée, qui viennent s’ajouter à ceux et celles héritées.
✤ Les classes dont elle hérite une autre classe sont appelées classes mères
ou classes de base.
✤ La classe qui hérite est appelée classe fille, classe dérivée ou classe
descendante.

77
L’HÉRITAGE

✴ Syntaxe:
class DerivedClassName : access-level BaseClassName
Où:
– access-level spécifie le type de dérivation
• private par défault
• public ou
• protected
• N’importe quelle classe peut servir de classe de base
• Une classe dérivée peut aussi être une classe de base
• Une classe peut dériver de plusieurs classes

78
HÉRITAGE SIMPLE (EXEMPLE)

class Point{
Point protected:
int x, y;
public:
Point_3D
Point (int =0, int =0);
void set (int a, int b);
Sphere };

class Sphere : public Point_3D{ class Point_3D : public Point{


private: protected:
double r; int z;
}; };

Point est la classe de base de la classe Point_3D


Point_3D est la classe de base de Sphere

79
RÈGLES SUR LES CONSTRUCTEURS ET LES
DESTRUCTEURS DES CLASSES DÉRIVÉES

✤ Le constructeur et le destructeur par défaut d’une classe de base sont toujours


appelés lorsqu’un objet d’une classe dérivée est créé ou détruit

class A{
public: class B : public A
A ( ){ {
cout<< “Appel du Constructeur par défaut de public:
A”<<endl; B (int a) {
} cout<<“Appel du constructeur de la classe
A (int a){ B”<<endl;
cout<<“Constructeur de la classe A avec un }
parametre”<<endl; };
}
};

Appel du Constructeur par défaut de A


B objDeriv (2);
Appel du constructeur de la classe B
RÈGLES SUR LES CONSTRUCTEURS ET LES
DESTRUCTEURS DES CLASSES DÉRIVÉES

Il est possible de spécifier un autre constructeur de la classe de base au lieur du


constructeur par défaut
class A{
public: class B : public A
A ( ){ {
cout<< “Appel du Constructeur par défaut de public:
A”<<endl; B (int a) : A(a) {
} cout<<“Appel du constructeur de la classe
A (int a){ B”<<endl;
cout<<“Appel du Constructeur de la classe A }
avec un parametre =”<<a<<endl; };
}
};

Appel du Constructeur de la classe A avec un parametre = 2


B objDeriv (2);
Appel du constructeur de la classe B
DÉFINITION DES MEMBRESPROPRES DE LA CLASSE
DÉRIVÉE

La classe dérivée peut aussi définir ses propres membres, en plus des membres
hérités de la classe de base.

class Point{ class Point_3D : public Point{


protected: private:
int x, y; int z;
public: public:
Point (int =0, int =0); Point_3D(int=0 , int =0, int =0)
void setXY (int a, int b); void setZ(int );
}; };

82
REDÉFINITION DES FONCTIONS DANS LA CLASSE
DÉRIVÉE
✤ Une classe dérivée peut redéfinir (override) les méthodes définies dans sa classe
mère. Avec le principe de redéfinition:
– Une méthode de la classe dérivée a la même signature que celle définie dans la
classe de base;
– une classe de base implémente , de sa propre manière, une méthode de la classe
de base
class Point{ class Point_3D : public Point{
protected: private:
int x, y; int z;
public: public:
Point (int =0, int =0); Point_3D(int=0 , int =0, int =0)
void setXY (int a, int b); void setZ(int );
void afficher ( ); void afficher ( );
}; };

Point P1 ( ); Point_3D P2 ( );
P1.afficher(); P2.setXY(2,3);
83 P2.afficher();
RÉCAPITULATIF SUR L’HÉRITAGE

✤ CBase est la classe de base


✤ CDerivee est la classe dérivée (héritage publique)
✤ La classe dérivée CDerivee peut:
✴ Hériter de tous les membres de sa classe de base à
CBase
l’exception du constructeur
✴ Accéder à tous les membres (public et protected) de la
classe de base
✴ Définir ses données membres privées CDerivee
✴ Fournir son propre constructeur
✴ Définir ses fonctions membres publiques
✴ Redéfinir les fonctions héritées de la classe de base

84
TYPES D’HÉRITAGE

! ! MOT-CLÉ UTILISÉ POUR L'HÉRITAGE


!
! ACCÈS AUX DONNÉES public protected private

! Mot-clé utilisé pour public public protected private


!
! les données et les protected protected protected private
! méthodes membres private interdit interdit interdit
!
Ainsi, les données publiques d'une classe mère deviennent soit publiques, soit
protégées, soit privées selon que la classe fille hérite en public, protégé ou en privé. Les
données privées de la classe mère sont toujours inaccessibles, et les données protégées
deviennent soit protégées, soit privées.
Il est possible d'omettre les mots-clés public, protected et private dans la syntaxe de
l'héritage. Dans ce cas, le compilateur utilise ‘private’ comme type d'héritage par défaut.
85
VI.1. HÉRITAGE PUBLIQUE
HÉRITAGE PUBLIQUE

class B : public A
{ // La classe B hérite des membres de la classe A
// sans changement dans le spécificateur d’accès
// des membres hérités
};

Classe de Base “Public” (A) Classe Dérivée (B)


membres “public” “public”
membres “protected” “protected”
membres “private” Hérités mais pas accessibles

86
HÉRITAGE PROTÉGÉ

class B : protected A
{ // La classe B hérite des membres de la classe A
// Les membres “public” deviennent “protected”
// Pas de changement pour les autres membres hérités
};

Classe de Base “Protected” (A) Classe Dérivée (B)


membres “public” “protected”
membres “protected” “protected”
membres “private” Hérités mais pas accessibles

87
HÉRITAGE PRIVÉ

class B : private A
{ // La classe B hérite des membres de la classe A
// Les membres “public” et “protected” deviennent
// “private”
};

Classe de Base “Private” (A) Classe Dérivée (B)


membres “public” “private”
membres “protected” “private”
membres “private” Hérités mais pas accessibles

88
HÉRITAGE MULTIPLE

Une classe peut dériver de plusieurs classes à la fois:

Syntaxe:

class derivedClass:public/protected/private baseClass1,


public/protected/private baseClass2{ …}, ……;

Exemple:

Point Couleur

PointColore

89
COMPATIBILITÉ ENTRE CLASSE DE BASE ET
CLASSE DÉRIVÉE
La compatibilité entre une classe dérivée et sa classe de base ne s’applique
que dans le cas de dérivation publique :`
✦ Conversion d’un objet d’un type dérivé à un objet d’un type de base;
✦ Conversion d’un pointeur (ou d’une référence) sur une classe dérivée en
un pointeur (ou une référence) sur une classe de base.
class Point{ class Point_3D : public Point{
protected: private:
int x, y; int z;
public: public:
Point (int =0, int =0); Point_3D(int=0 , int =0, int =0)
}; };

Point P1; Point *P1; Point_3D *P2; //Ou références


point_3D P2; P1= P2; // possible
P1 = P2; // conversion possible P2 = P1; // Impossible
P2 = P1; // conversion impossible //Possible
P2 = static_cast <Point_3D *> P1;
90
COMPATIBILITÉ ENTRE CLASSE DE BASE ET
CLASSE DÉRIVÉE
class Point{ class Point_3D : public Point{
protected: private:
int x, y; int z;
public: public:
Point (int =0, int =0); Point_3D(int=0 , int =0, int =0)
void afficher ( ); void afficher ( );
}; };

Pt1 Pt2
&B
Point A(1,2); &A
point_3D B (-1, -2, 4);
Point *Pt1 = &A; -1
point_3D *Pt2 = &B;
1
Pt1->afficher(); //Point::afficher() -2
Pt2->afficher(); //Point_3D::afficher()
2
4
afficher()
afficher()
91
COMPATIBILITÉ ENTRE CLASSE DE BASE ET
CLASSE DÉRIVÉE
Pt1 Pt2
&B
&A

Point A(1,2); -1
point_3D B (-1, -2, 4); 1
Point *Pt1 = &A; -2
point_3D *Pt2 = &B;
2
pt1 = pt2; 4
Pt1->afficher(); //Point::afficher()
Pt2->afficher(); //Point_3D::afficher() afficher()
afficher()

✤ Le choix de la méthode appelée est réalisé par le compilateur.


✤ La méthode à appeler est définie une fois pour toute et ne pourra évoluer
au fil des changements éventuels de type de l’objet pointé.
✤ Le type des objets pointés par Pt1 et Pt2 est décidé et fixé au moment de
la compilation.
92
FONCTIONS VIRTUELLES ET POLYMORPHISME

Polymorphisme:

❖ Dans la relation d’héritage, un pointeur sur un type d’objet de la classe de


base peut recevoir l’adresse de n’importe quel objet de la classe dérivée.
❖ L’appel d’une méthode pour un objet pointé consiste à appeler la méthode

correspondant au type du pointeur (selon la déclaration), et non pas au


type effectif de l’objet pointé lui même: Liaison statique.
❖ Le type d’un objet pointé est déterminé au moment de la compilation (le

compilateur considère que l’objet pointé a le type du pointeur).


❖ Liaison dynamique ou polymorphisme: L’habilité d’un objet pointé de
n’importe quelle classe de répondre proprement aux appels des fonctions
similaires.
❖ Le polymorphisme peut être mis en oeuvre en utilisant la notion de

fonctions virtuelles.
FONCTIONS VIRTUELLES

❖ Liaison dynamique: Le type d’objets n’est pas requis quand on


compile les fonctions virtuelles.

❖ Le mécanisme des fonctions virtuelles va permettre d’ appeler la


méthode correspondante au type de l’objet réellement désigné
par un pointeur.

❖ Pour ce faire, il faut déclarer les fonctions comme virtuelle (mot


clé virtual) ==> fonctions polymorphes.

❖ “virtual” indique au compilateur que les appels de la fonction


polymorphes doivent utiliser une liaison dynamique et non plus
la liaison statique.
FONCTIONS VIRTUELLES

class Point { Point.h class Point_3D : public Point{ Point3D.h


protected: private:
int x, y; int z;
public: public:
Point(int a = 0, int b = 0): x(a), y(b){ } Point_3D(int a = 0, int b = 0, int c=0): x(a),
virtual void afficher ( ){ y(b),z(c){ }
cout<<“Je suis un point 2D:”; virtual void afficher ( ){
cout<<(“<<x<<“,”<<y<<“)”<<endl; cout<<“Je suis un point 3D:”;
} cout<<(“<<x<<“,”<<y<<“,“<<z)”<<endl; }
}; };

95
FONCTIONS VIRTUELLES

Synthèse

✦ Les appels aux méthodes virtuelles (polymorphes) doit se faire à l’aide d’un
pointeur sur un objet ou bien à l’aide d’une référence.

✦ Les fonctions virtuelles sont souvent introduites dans des classes placées à
des niveaux si élevés de la hiérarchie (d’héritage) qu’on ne peut pas leur
donner une implémentation utile ni même vraisemblable.

✦ Le destructeur doit être aussi une méthode virtuelle

96
TEMPLATES (GÉNÉRICITÉ)

✤ Un modèle (patron) indépendant de type qui peut traiter


plusieurs types de données :
• Programmation générique
• Réutilisabilité du code

✤ Fonctions Templates :
• des fonctions qui ont le même comportement avec des types de
données différents

✤ Classes Templates :
• Définissent des classes modèles dans lesquelles des types de
données ben spécifiques peuvent être utilisées pour créer de
nouvelles classes

97
FONCTION TEMPLATE

✤ Besoin d’écrire différentes routines pour appliquer la même opération sur


différents types de données.

int maximum(int a, int b, int c) {


int max = a;
if (b > max) max = b;
if (c > max) max = c;
return max; }
float maximum(float a, float b, float c){
float max = a;
if (b > max) max = b;
if (c > max) max = c;
return max; }
double maximum(double a, double b, double c){
double max = a;
if (b > max) max = b;
if (c > max) max = c;
return max; }
FONCTION TEMPLATE

✦ La logique de ces trois fonctions est exactement la même mais le type des
données est différent.
✦ Une fonction template permet d’écrire une fois le même code et est
utilisée pour toutes les données —> fonction générique.
✦ fonction générique pour trouver la valeur maximale:
Template <class T>
T maximum(T a, T b, T c) {
T max = a;
if (b > max) max = b;
if (c > max) max = c;
return max; }
✦ L’utilisation de la fonction template maximum se fait de la façon suivante:

int a, b, c;

int m = maximum(a, b, c);
✦ maximum(a, b, c) appellera la fonction template avec T ==int et la
fonction retourne un int
99
FONCTION TEMPLATE

Remarques

✦ Chaque appel à la fonction maximum() avec un type de données


spécifique, oblige le compilateur à générer une fonction basée sur le
type défini en utilisant la fonction template.
✦ Il n’est pas toujours possible d’utiliser une fonction template pour
des types définis par un utilisateur :
• seulement pour les types définis qui supportent toutes les opérations
utilisées dans la fonction (exemple: la somme, << etc)
CLASSES TEMPLATES

✦ Il est parfois souhaitable de permettre le stockage de différents


types de données dans une classe.
✦ Par exemple, une classe valeurNum qui généralise le cas de tous les
types de données numériques ( int, float, double, char), ou une
classe qui gère tous les types des tableaux (int, float, double, char,
complexes, etc)
CLASSES TEMPLATES

✦ Pour créer une classe template on utilise la syntaxe suivante:


template< class T >
– T est un paramètre de type
– Quand une classe template est instanciée, T est remplacé par un
type bien défini.
✦ Pour définir une fonction membre on utilise la syntaxe suivante:
className< T >:: memberName.
✦ Pour utiliser une classe template :
– ClassName<type défini> variable;
CLASSES TEMPLATES

template <class T> class Point { Point.h


T x, y;
public:
Point(T abs = 0, T ord = 0): x= abs, y =ord{ }
void afficher ( );
};
template <class T> void Point<T>::afficher(){
cout<<“Mes coordonnées sont:”<<x<<“,”<<y<<endl;
}

#include<iostream> main.cpp
using namespace std;
#include “Point.h”
int main ( ) {
Point <int> pi (-1,5); pi.afficher( );
Point <double> pd (2.5, 4.8); pd.afficher( );
Point <unsigned int> pui (2,4); pui.afficher ( );
Point <char> pc(‘a’, ‘d’); pc.afficher ( );
return 0;
}
CLASSES TEMPLATES