Vous êtes sur la page 1sur 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

LE LANGAGE C++

TODO :
-

Flux dentres/sorties
5.1.4 : dclaration daccs ( revoir)

v1.5.4.2 27/05/2010
peignotc(at)arqendra(dot)net / peignotc(at)gmail(dot)com
Toute reproduction partielle ou intgrale autorise selon les termes de la licence Creative Commons (CC) BY-NC-SA : Contrat
Paternit-Pas d'Utilisation Commerciale-Partage des Conditions Initiales l'Identique 2.0 France, disponible en ligne
http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ ou par courrier postal Creative Commons, 171 Second Street, Suite 300,
San Francisco, California 94105, USA. Merci de citer et prvenir lauteur.

1 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

TABLE DES MATIRES


0

PROLOGUE............................................................................................................ 8

INTRODUCTION AU LANGAGE C++ ............................................................... 9

NOTIONS DE BASE............................................................................................ 10
2.1
2.2

INTRODUCTION ........................................................................................................................ 10
AMLIORATIONS PAR RAPPORT AU LANGAGE C ...................................................................... 10

2.2.1
2.2.1.1
2.2.1.2

2.2.2
2.2.2.1
2.2.2.2
2.2.2.3
2.2.2.4
2.2.2.5
2.2.2.6
2.2.2.7
2.2.2.8
2.2.2.9

2.2.3
2.2.3.1
2.2.3.2
2.2.3.3
2.2.3.4

Entres/sorties ................................................................................................................................10
Entres/sorties standard ........................................................................................................................... 10
Entres/sorties standard par flux ............................................................................................................. 10

Variables.........................................................................................................................................11
Dclaration .............................................................................................................................................. 11
Type boolen ........................................................................................................................................... 11
Constantes ............................................................................................................................................... 12
Structures................................................................................................................................................. 12
numrations........................................................................................................................................... 12
Conversion de type.................................................................................................................................. 12
Oprateur de rsolution de porte............................................................................................................ 13
Rfrences ............................................................................................................................................... 13
Allocation de mmoire ............................................................................................................................ 13

Fonctions ........................................................................................................................................14
Paramtres par dfaut .............................................................................................................................. 14
Fonctions inline ....................................................................................................................................... 14
Utilisation des rfrences ........................................................................................................................ 14
Surcharge................................................................................................................................................. 15

LES OBJETS ET LES CLASSES ........................................................................ 17


3.1

LA PROGRAMMATION ORIENTE OBJET ................................................................................... 17

3.1.1
3.1.2

3.2

LOBJET................................................................................................................................... 17

3.2.1
3.2.2
3.2.3
3.2.4

3.3

Introduction : rappels sur les structures ........................................................................................17


Dfinitions ......................................................................................................................................18
Principes de classe et d instance de classe ........................................................................18
Principe d encapsulation ..........................................................................................................20

CRITURE DUNE CLASSE ........................................................................................................ 21

3.3.1
3.3.2
3.3.3
3.3.4
3.3.5
3.3.6

3.4

Lapproche objet ............................................................................................................................17


Atouts..............................................................................................................................................17

Dclaration dune classe................................................................................................................21


Implmentation des mthodes.........................................................................................................21
Principe de constructeur ..........................................................................................................22
Principe de destructeur ............................................................................................................25
Le pointeur this...............................................................................................................................26
Les mthodes accesseurs ................................................................................................................26

COMPLMENTS ........................................................................................................................ 27

3.4.1
3.4.2
3.4.3
3.4.4
3.4.5
3.4.6

Constructeur de recopie .................................................................................................................27


Instanciation et destruction dun attribut-objet..............................................................................30
Membres statiques ..........................................................................................................................34
Objets anonymes.............................................................................................................................36
Objets constants et mthodes constantes........................................................................................36
Classes, mthodes et fonctions amies .............................................................................................37
2 / 104

Programmation Oriente Objet > Langage C++ > Cours

SURCHARGE DOPRATEURS........................................................................ 40
4.1
4.2
4.3

INTRODUCTION ........................................................................................................................ 40
PRINCIPES ET DFINITIONS ...................................................................................................... 40
IMPLMENTATION ................................................................................................................... 41

4.3.1
4.3.2

LHRITAGE SIMPLE ................................................................................................................ 45

5.1.1
5.1.2
5.1.3
5.1.4

5.2

5.3

Principes.........................................................................................................................................45
Implmentation ...............................................................................................................................46
Relations entre classe de base et classe drive.............................................................................46
Modes de drivation .......................................................................................................................49

LE POLYMORPHISME................................................................................................................ 50

5.2.1
5.2.2
5.2.3
5.2.4
5.2.5

Hirarchie des classes ....................................................................................................................50


Conversion vers une classe de base................................................................................................51
Gnralisation ................................................................................................................................52
Mthodes virtuelles.........................................................................................................................55
Mthodes virtuelles pures et classes abstraites..............................................................................56

LHRITAGE MULTIPLE ............................................................................................................ 58

5.3.1
5.3.2
5.3.3
5.3.4

Principes.........................................................................................................................................58
Implmentation ...............................................................................................................................58
Relations entre classes de base et classe drive ...........................................................................59
Hritage virtuel ..............................................................................................................................59

LA GNRICIT ................................................................................................. 62
6.1
6.2
6.3

Surcharge doprateur par une mthode........................................................................................41


Surcharge doprateur par une fonction ........................................................................................44

LHRITAGE DE CLASSES............................................................................... 45
5.1

v1.5.4.2 27/05/2010

PRINCIPES ET DFINITIONS ...................................................................................................... 62


LES MTHODES ET FONCTIONS GNRIQUES ............................................................................ 62
LES CLASSES GNRIQUES ....................................................................................................... 64

LES EXCEPTIONS .............................................................................................. 67


7.1
7.2
7.3

INTRODUCTION ........................................................................................................................ 67
DFINITIONS............................................................................................................................ 68
IMPLMENTATION ................................................................................................................... 68

7.3.1
7.3.2

Interception et gestion des exceptions ............................................................................................68


Lancement des exceptions ..............................................................................................................71

3 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

TABLE DES ANNEXES


A MOTS-CLEFS DU LANGAGE C++ ................................................................... 74
A.1 ORDRE ALPHABTIQUE............................................................................................................ 74
A.2 CATGORIES............................................................................................................................ 74
A.2.1
A.2.2
A.2.3
A.2.4
A.2.5
A.2.6
A.2.7
A.2.8
A.2.9
A.2.10
A.2.11

Classes et membres.........................................................................................................................74
Modificateurs de visibilit de membres ..........................................................................................74
Types primitifs de variables et attributs .........................................................................................75
Modificateurs dattributs................................................................................................................75
Modificateurs de mthodes.............................................................................................................75
Modificateurs de variables et dattributs .......................................................................................75
Modificateurs de fonctions et de mthodes.....................................................................................76
Types de variables et attributs complexes ......................................................................................76
Structures de contrle.....................................................................................................................76
Gestion des exceptions....................................................................................................................76
Autres..............................................................................................................................................76

B DLIMITEURS ET OPRATEURS ................................................................... 77


B.1 DLIMITEURS .......................................................................................................................... 77
B.2 OPRATEURS ........................................................................................................................... 77
B.2.1
B.2.2
B.2.3
B.2.4
B.2.5
B.2.6

Oprateur daffectation ..................................................................................................................77


Oprateurs arithmtiques ...............................................................................................................77
Oprateurs binaires........................................................................................................................77
Oprateurs combins......................................................................................................................78
Oprateurs dvaluation dexpression ...........................................................................................78
Oprateurs divers ...........................................................................................................................78

B.3 PRIORIT DES OPRATEURS ET DLIMITEURS ........................................................................... 78

C LA STL : LIBRAIRIE STANDARD.................................................................... 79


C.1 INTRODUCTION ........................................................................................................................ 79
C.2 PRSENTATION ........................................................................................................................ 79
C.2.1
C.2.2
C.2.3

Les espaces de noms .......................................................................................................................79


La gestion des chanes de caractres .............................................................................................80
Les structures de donnes...............................................................................................................80

C.2.3.1
C.2.3.2
C.2.3.3

Les conteneurs......................................................................................................................................... 81
Les itrateurs ........................................................................................................................................... 81
Les algorithmes ....................................................................................................................................... 81

D CORRESPONDANCE UML ET C++ ................................................................. 82


D.1 STRUCTURE STATIQUE ............................................................................................................. 82
D.1.1 Classes............................................................................................................................................82
D.1.1.1
D.1.1.2
D.1.1.3

Classe ...................................................................................................................................................... 82
Classe abstraite ........................................................................................................................................ 82
Classe paramtrable................................................................................................................................. 82

D.1.2 Paquetage .......................................................................................................................................83


D.1.3 Membres .........................................................................................................................................83
D.1.3.1
D.1.3.2
D.1.3.3

Membre ................................................................................................................................................... 83
Implmentation des mthodes ................................................................................................................. 84
Visibilit .................................................................................................................................................. 84
4 / 104

Programmation Oriente Objet > Langage C++ > Cours

D.1.3.4
D.1.3.5

v1.5.4.2 27/05/2010

Membre statique ...................................................................................................................................... 84


Mthodes virtuelle et virtuelle pure......................................................................................................... 85

D.2 ASSOCIATIONS ........................................................................................................................ 85


D.2.1 Association simple ....................................................................................................................85
D.2.1.1
D.2.1.2
D.2.1.3
D.2.1.4

Association unidirectionnelle 1-1............................................................................................................ 85


Association unidirectionnelle 1-plusieurs ............................................................................................... 86
Association bidirectionnelle .................................................................................................................... 87
Association rflexive ............................................................................................................................... 87

D.2.2 Agrgation ......................................................................................................................................88


D.2.2.1
D.2.2.2
D.2.2.3
D.2.2.4

Agrgation 1-1......................................................................................................................................... 88
Agrgation 1-plusieurs ............................................................................................................................ 89
Agrgation navigable .............................................................................................................................. 89
Agrgation rflexive................................................................................................................................ 90

D.2.3 Composition....................................................................................................................................91
D.2.3.1
D.2.3.2

Composition 1-1 ...................................................................................................................................... 91


Composition 1-plusieurs.......................................................................................................................... 92

D.3 SPCIALISATIONS / GNRALISATIONS .................................................................................... 92


D.3.1 Spcialisation partir dune classe ...............................................................................................93
D.3.2 Spcialisation partir de plusieurs classes....................................................................................93

D.4 CLASSE DASSOCIATION .......................................................................................................... 93


D.5 DPENDANCES ........................................................................................................................ 94
D.5.1
D.5.2
D.5.3
D.5.4

Dpendance du type <<instanciate>> ..........................................................................................95


Dpendance du type <<create>>..................................................................................................95
Dpendance du type <<call>>......................................................................................................96
Dpendance du type <<bind>>.....................................................................................................96

E RFRENCE ........................................................................................................ 98
E.1

PROGRAMMATION ORIENTE OBJET ....................................................................................... 98

E.1.1
E.1.2

Gnralits .....................................................................................................................................98
Principes.........................................................................................................................................98

E.1.2.1
E.1.2.2
E.1.2.3

E.2

Lencapsulation ....................................................................................................................................... 98
Lhritage de classe ................................................................................................................................. 98
Le polymorphisme................................................................................................................................... 98

EXCUTION ET RESSOURCES .................................................................................................... 99

E.2.1

Allocation de mmoire....................................................................................................................99

E.2.1.1
E.2.1.2
E.2.1.3

E.2.2

Allocation statique................................................................................................................................... 99
Allocation sur la pile ............................................................................................................................... 99
Allocation dans le tas ............................................................................................................................ 101

Appel de procdure.......................................................................................................................102

F BIBLIOGRAPHIE .............................................................................................. 104

5 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

TABLE DES ILLUSTRATIONS


Figure 3.1 : exemple de structure _________________________________________________________________________________________17
Figure 3.2 : classe et instance de classe ____________________________________________________________________________________19
Figure 3.3 : reprsentation UML dune classe _______________________________________________________________________________19
Figure 3.4 : exemple dune classe _________________________________________________________________________________________19
Figure 3.5 : exemple de cration dinstances diffrentes partir dune mme classe __________________________________________________19
Figure 3.6 : exemple dune classe avec dtail des attributs et mthodes ____________________________________________________________20
Figure 3.7 : exemple dune classe avec dtail des attributs et mthodes, et de leur visibilit ____________________________________________20
Figure 3.8 : exemple de dclaration dune classe _____________________________________________________________________________21
Figure 3.9 : exemple dune classe avec un constructeur par dfaut________________________________________________________________22
Figure 3.10 : exemple dune classe avec plusieurs constructeurs _________________________________________________________________23
Figure 3.11 : exemple dune classe avec un constructeur avec des valeurs par dfaut pour tous les paramtres _____________________________24
Figure 3.12 : exemple dune classe avec destructeur___________________________________________________________________________25
Figure 3.13 : exemple dune classe avec les accesseurs dun attribut ______________________________________________________________26
Figure 3.14 : exemple dune classe sans constructeur de recopie _________________________________________________________________28
Figure 3.15 : exemple dune classe avec constructeur de recopie _________________________________________________________________29
Figure 3.16 : reprsentation dune classe avec un attribut de type objet____________________________________________________________30
Figure 3.17 : exemple dune classe possdant un attribut de type objet ____________________________________________________________30
Figure 3.18 : exemple de dclaration dune classe possdant un attribut-objet sans constructeur par dfaut _______________________________31
Figure 3.19 : exemple de dclaration dune classe possdant plusieurs attributs-objets sans constructeur par dfaut _________________________32
Figure 3.20 : exemple de dclaration dune classe avec des membres statiques ______________________________________________________35
Figure 4.1 : exemple dune classe avec surcharge de loprateur + _______________________________________________________________41
Figure 4.2 : exemple dune classe avec surcharge des oprateurs + et = ___________________________________________________________42
Figure 4.3 : exemple dune classe avec plusieurs surcharges pour un oprateur _____________________________________________________43
Figure 5.1 : reprsentation UML dune relation dhritage simple________________________________________________________________45
Figure 5.2 : exemple dun hritage simple entre deux classes ____________________________________________________________________45
Figure 5.2 : exemple dutilisation de lhritage_______________________________________________________________________________46
Figure 5.3 : exemple dimplmentation dun hritage simple ____________________________________________________________________46
Figure 5.4 : exemple de hirarchie de classes ________________________________________________________________________________51
Figure 5.5 : exemple de conversion de type dans une hirarchie de classes _________________________________________________________52
Figure 5.6 : exemple de mise en uvre de la gnralisation _____________________________________________________________________53
Figure 5.7 : exemple de rdfinition dun membre dans une relation de gnralisation ________________________________________________54
Figure 5.8 : exemple de mise en uvre dune mthode virtuelle __________________________________________________________________55
Figure 5.9 : exemple de propagation dune dclaration virtuelle _________________________________________________________________56
Figure 5.10 : exemple de mise en uvre dune mthode virtuelle pure et dune classe abstraite _________________________________________57
Figure 5.11 : reprsentation UML dun hritage multiple_______________________________________________________________________58
Figure 5.12 : exemple dhritage multiple ___________________________________________________________________________________58
Figure 5.13 : exemple dun cas de conflit dans un hritage multiple_______________________________________________________________59
Figure 6.1 : reprsentation dune classe gnrique____________________________________________________________________________64
Figure D.1 : reprsentation UML dune classe _______________________________________________________________________________82
Figure D.2 : reprsentation UML dune classe abstraite________________________________________________________________________82
Figure D.3 : reprsentation UML dune classe paramtrable ____________________________________________________________________82
Figure D.4 : reprsentation UML dun paquetage ____________________________________________________________________________83
Figure D.5 : reprsentation UML dune classe et de ses membres ________________________________________________________________83
Figure D.6 : reprsentation UML dune classe, de ses membres et de leur visibilit___________________________________________________84
Figure D.7 : reprsentation UML dune classe avec des membres statiques _________________________________________________________84
Figure D.8 : reprsentation UML dune classe avec une mthode virtuelle et une mthode virtuelle pure __________________________________85
Figure D.9 : reprsentation UML dune association ___________________________________________________________________________85
Figure D.10 : reprsentation UML dune association unidirectionnelle 1-1 _________________________________________________________85
Figure D.11 : reprsentation UML dune association unidirectionnelle 1-plusieurs___________________________________________________86
Figure D.12 : reprsentation UML dune association bidirectionnelle _____________________________________________________________87
Figure D.13 : reprsentation UML dune association rflexive___________________________________________________________________87
Figure D.14 : reprsentation UML dune agrgation __________________________________________________________________________88
Figure D.15 : reprsentation UML dune agrgation 1-1 _______________________________________________________________________88
Figure D.16 : reprsentation UML dune agrgation 1-plusieurs _________________________________________________________________89
Figure D.17 : reprsentation UML dune agrgation navigable __________________________________________________________________89
Figure D.18 : reprsentation UML dune agrgation rflexive ___________________________________________________________________90
Figure D.19 : reprsentation UML dune composition _________________________________________________________________________91
Figure D.20 : reprsentation UML dune composition 1-1 ______________________________________________________________________91
Figure D.21 : reprsentation UML dune composition sous forme de classe imbrique ________________________________________________91
Figure D.22 : reprsentation UML dune composition 1-plusieurs ________________________________________________________________92
Figure D.23 : reprsentation UML dune spcialisation / gnralisation ___________________________________________________________92
6 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Figure D.24 : reprsentation UML dune spcialisation partir dune classe _______________________________________________________93
Figure D.25 : reprsentation UML dune spcialisation partir de plusieurs classes _________________________________________________93
Figure D.26 : reprsentation UML dune classe dassociation ___________________________________________________________________93
Figure D.27 : reprsentation UML dune dpendance _________________________________________________________________________95
Figure D.28 : reprsentation UML dune dpendance du type <<instanciate>> _____________________________________________________95
Figure D.29 : reprsentation UML dune dpendance du type <<create>>_________________________________________________________95
Figure D.30 : reprsentation UML dune dpendance du type <<call>> __________________________________________________________96
Figure D.31 : reprsentation UML dune dpendance du type <<bind>> __________________________________________________________96
Figure E.1 : exemple dallocations dynamiques sur la pile _____________________________________________________________________100
Figure E.2 : exemple dallocations statiques sur la pile _______________________________________________________________________100
Figure E.3 : exemple dallocations dynamiques dans le tas_____________________________________________________________________101
Figure E.4 : appels de procdures allous sur la pile _________________________________________________________________________102
Figure E.5 : passage de paramtres dentre et rcupration de la valeur renvoye lors de lappel dune procdure ________________________103

7 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

0 PROLOGUE
Le contenu du prsent document se focalise principalement sur les aspects de Programmation Oriente Objet
appliqus au langage C++ et tient pour acquis tous les lments de base du langage, qui ne sont ni plus ni moins que
ceux issus du langage C (nda : voir le cours Le langage C du mme auteur).
La matrise de notions telles que les principes de mot-clef , d instruction , et de variable , les structures de
contrle, les tableaux, les fonctions, les pointeurs et les types de variables complexes principalement les structures
est imprative pour apprhender les nouveaux lments amens.
dfaut, la bonne connaissance des lments dun langage proche en termes de fondamentaux et de syntaxe,
comme Java ou C# par exemple, doit permettre de saisir le contenu sans trop de difficults ; dans certains cas, on
veillera nanmoins compulser des documents ddis au langage C ou C++, car certaines notions demeurent
spcifiques ces langages (les pointeurs nexistent pas en Java et sont peu utiliss en C# par exemple).

8 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

1 INTRODUCTION AU LANGAGE C++


Le langage C++ est un langage de programmation orient objet qui a t conu au dbut des annes 80 sur les bases
du langage C 1. Lide tait de rajouter lapproche POO 2 au langage C, langage ayant connu un franc succs, et de
profiter ainsi de la popularit de ce dernier pour permettre un passage facilit la programmation objet 3.
Le C++, bti sur le C, reprend donc la quasi-intgralit des concepts que celui-ci met en uvre, le mme jeu
dinstructions de base, la mme syntaxe, ainsi que laccs aux librairies standard du C. Le C++ peut ainsi tre
considr comme un sur-ensemble du C 4.
Outre les aspects de POO, le C++ permet aussi, entre autres, une gestion plus efficace des affichages et saisies,
apporte de nouveaux oprateurs, et plus de souplesse dans la dclaration des variables, tout en tant un langage plus
fortement typ que le C 5.
Nanmoins, le C++ souffre des dfauts de sa conception, et parce quil a t le premier langage orient objet
largement utilis, tout comme le fait quil soit bas sur un langage qui lui ne lest pas, reste un langage laborieux,
parfois confus, qui demande une trs bonne matrise du C et des concepts objets.
Les avantages du langage C++ sont :
V continuit du langage C ;
V possibilit de travailler en objet (C++) ou en squentiel (C) ;
V portable (recompilation ncessaire tout de mme) ;
V rapidit dexcution ;
V largement diffus et utilis.
Les inconvnients du langage C++ sont :
V plus complexe que dautres langages objet ;
V confusion possible avec le langage C.
Le langage C++ est le langage objet historique et reste une rfrence incontournable de la programmation dans
le milieu industriel. Par ailleurs, nonobstant ses lourdeurs, ltude du C++ est une bonne passerelle pour la
programmation objet avec des langages de plus haut niveau ; et par rapport auxquels lexcution dun programme crit
en C++ est souvent plus rapide.

1
2
3

4
5

Le concepteur du langage C++ est Bjarne Stroustrup.


Programmation Oriente Objet.
Le premier nom du langage C++ tait ainsi C with classes ( C avec des classes ), la classe tant llment smantique fondamental en
programmation objet.
On peut dire que le C++ est un C incrment (++).
Vrification plus rigoureuse du type dune variable.
9 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

2 NOTIONS DE BASE
2.1 INTRODUCTION
Le langage C++ est donc pleinement bas sur le langage C, et est identique sur tous les points importants :
V dveloppement : langage compil, chane de compilation, sources sous forme de fichiers texte, structure des
fichiers source (lextension nest plus .c bien sr mais .cpp) ;
V commentaires : multi-lignes et mono-ligne ;
V variables : types, manipulation et oprateurs ;
V entres/sorties : affichages et saisies ;
V structures de contrles : oprateurs, structures alternatives et itratives ;
V tableaux et chanes de caractres : principes et manipulation ;
V fonctions : librairies standard du C, fonctions utilisateur ;
V pointeurs : principes, manipulation et application ;
V types de variables complexes : structures, etc. ;
V entres/sorties sur fichiers : lecture et criture ;
V
Nanmoins, mis part les aspects de programmation objet, C++ propose aussi certaines amliorations et spcificits
par rapport au C.

2.2 AMLIORATIONS PAR RAPPORT AU LANGAGE C


2.2.1
2.2.1.1

Entres/sorties
Entres/sorties standard

Linterfaage entre une application et le systme dexploitation, qui est une entit externe lapplication, met en
uvre des flux dentres/sorties 1. Comme ces flux sont les plus utiliss (quasiment constamment lors de lutilisation
de la machine), on les appelle flux standard 2 ou flux dentres/sorties standard :
V entre standard : par dfaut le clavier, appel stdin (fonctions scanf()) ;
V sortie standard : par dfaut la console (lcran), appel stdout (fonctions printf()) ;
V erreur standard : par dfaut est aussi la console, appel stderr.

2.2.1.2

Entres/sorties standard par flux

Pour effectuer des entres/sorties standard, on peut utiliser les fonctions scanf() et printf() de la librairie
standard du C, mais aussi les entres/sorties standard par flux de la bibliothque iostream.h :
V entre standard : flux cin ;
V sortie standard : flux cout ;
V erreur standard : flux cerr ;
V erreur standard bufferise : flux clog.
On manipule ces flux laide doprateurs spcifiques :
V lecture de valeur dun flux dentre : oprateur >> (macro pour la fonction istream& operator<<()) ;
V criture de valeur dans un flux de sortie : oprateur << (macro pour la fonction ostream& operator>>()).
1
2

Un flux est un moyen de communication sriel : les donnes sont traites dans lordre dans lequel elles sont envoyes.
Les flux standard sont normment utiliss dans le monde Unix, au niveau du shell.
10 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : #include <iostream.h>


int main(void)
{
int i;
float f = 1.23;
char ch[20] = "bonjour\n";
cout << "saisir un entier ";
cin >> i;
// saisie d'une valeur et stockage dans la variable i
cout << "i=" << i << "\nf=" << f << "\nch=" << ch;
// affichage de valeurs
return 0;
}

Lutilisation des entres/sorties standard par flux est plus rapide 1, et la taille mmoire cre la compilation est
rduite 2 ; de plus, le type est vrifi automatiquement, limitant ainsi les risques daffichage erron.
On peut modifier la manire dont les donnes sont lues ou crite dans le flux, en crivant un ou plusieurs
manipulateurs dans le flux, dfinis dans la bibliothque iomanip.h :
V dec : lecture/criture dun entier en dcimal ;
V oct : lecture/criture dun entier en octal ;
V hex : lecture/criture dun entier en hexadcimal ;
V endl : insertion dun saut de ligne et vidage des buffers ;
V setprecision(int) : affichage de la valeur avec un nombre de chiffres prcis (virgule dcimale non
incluse) 3 ;
3
V setw(int) : affichage format dune longueur du nombre de caractres prcis (remplissage avec le
caractre dfini par setfill(), ou bien par dfaut par le caractre espace) ;
3
V setfill(char) : dfinition du caractre de remplissage utilis avec setw() ;
V flush : vidage des buffers aprs criture.
Ex. : #include <iostream.h>
#include <iomanip.h>

int main(void)
{
int i = 1234;
float f = 54.6553;
cout << setw(10) << setfill('*') << i << endl;
cout << setw(8) << setprecision(5) << f << endl;
return 0;
}

2.2.2
2.2.2.1

// affichage: "******1234"
// affichage: "**54.655"

Variables
Dclaration

La dclaration dune variable peut tre ralise nimporte o dans le code, et plus seulement en dbut de bloc. La
porte reste identique, cest--dire quelle reste dfinie dans le bloc de code de dclaration.
Ceci est notamment utile pour les compteurs de boucle, afin dviter que leur dclaration ne perturbe la lisibilit.
Ex. : int i;

cin >> i;
int k = 5;
for ( int j=0 ; j<5 ; j++ ) cout << i+j << " "; // j n'existe que dans le for ()

2.2.2.2

Type boolen

Le C++ inclut un nouveau type de variables, le type boolen, dfini par le mot-clef bool. Ce type ne peut donc
prendre que 2 valeurs : true ou false.

1
2
3

Lanalyse est ralise la compilation, au lieu dtre faite lexcution.


Seul le code ncessaire est compil, au lieu dinclure le code ncessaire tous les formats disponibles.
La dfinition dune valeur avec ce manipulateur reste valide jusqu la fin du programme ou bien jusqu la dfinition suivante.
11 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ce type est utilis partout o, en langage C, tait utilise une variable entire de valeur 0 ou 1, comme :
V le rsultat dune opration logique (&&, ||, etc.) ;
1
V lvaluation dune expression (tests, etc.) .
Ex. : bool flag // dfinition d'une variable boolenne
if ( flag ) { ... }
if ( !flag ) { ... }

2.2.2.3

// identique if ( flag == true )


// identique if ( flag == false )

Constantes

On peut dclarer une variable constante, sans utiliser la directive prprocesseur #define, avec le modificateur
const utiliser suivant la syntaxe const type_variable nom_variable = valeur.
Ex. : const int i = 2;

// initialisation obligatoire de la valeur pour une constante

Nb : Dfinir un pointeur constant (type* const ptr) et un pointeur sur une constante (const type* ptr) sont
deux choses diffrentes. Dans le premier cas, ladresse ne peut pas tre modifie (le pointeur nest pas navigable ) ;
dans le second, la valeur pointe ne peut pas tre modifie. Il est dailleurs possible de dfinir un pointeur constant sur
une constante (const type* const ptr) ; ni ladresse ni la valeur ne peuvent tre modifies.

2.2.2.4

Structures

Lors de la dfinition dune structure, il nest plus ncessaire de crer un type synonyme (avec le mot-clef
typedef) pour ainsi saffranchir de la syntaxe struct nom_structure. Cette dfinition alloue automatiquement le

nom donn au nouveau type.


Ex. : struct Personne {
char initiale;
int age;

// dfinition d'un nouveau type utilisateur

};
int main(void)
{
Personne eleve1;
...
}

2.2.2.5

// utilisation du type utilisateur

numrations

Tout comme les structures, lors de la dfinition dune numration, il nest plus ncessaire de crer un type
synonyme (avec le mot-clef typedef) pour saffranchir de la syntaxe enum nom_enumeration. Cette dfinition
alloue automatiquement le nom donn au nouveau type.
Ex. : enum semaine {lun, mar, mer, jeu, ven, sam, dim};
semaine jour;
jour = mar;

Au contrario du langage C, une numration nest pas une liste dentiers, et une variable numre ne peut prendre
pour valeur que lune des valeurs du type numr auquel elle appartient. Il est malgr tout possible de lire une
interprtation de la valeur entire de la variable numre.
Ex. : int i = sam;

// conversion implicite en int, i vaut 5


cout << jour << endl;
// affichage: "1" (mar)

2.2.2.6

Conversion de type

La conversion de type (transtypage) peut tre ralise syntaxiquement de 2 manires :


V (nouveau_type) expression_ou_variable ;
V nouveau_type (expression_ou_variable).
Ex. : double d = 2.42;
int i, j;
i = (int) d;
j = int (d);

// transtypage classique

Avec une valeur entire, il est toujours possible dcrire if ( x ) { ... } mais il est vivement conseill dcrire explicitement
if ( x != 0 ) { ... }.
12 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Nb : La conversion explicite de type est souvent utilise avec les pointeurs du type void*.

2.2.2.7

Oprateur de rsolution de porte

On peut accder une variable dclare en dehors du bloc de code courant en utilisant loprateur de rsolution de
porte :: suivant la syntaxe ::nomVariable. Cet oprateur permet gnralement daccder ainsi une variable
globale possdant un homonyme en local.
Ex. : int i = 4;
int main(void)
{
int i = 10;
cout << i << endl;
cout << ::i << endl;
return 0;

// affichage: "10"
// affichage: "4"

Nb : Malgr lexistence de cet oprateur, et comme toujours, il est conseill dutiliser des noms de variables
diffrents pour des variables diffrentes, et donc il ne faut lutiliser quen cas de rel besoin.

2.2.2.8

Rfrences

Avec les pointeurs on manipule des adresses de manire explicite ; on peut aussi manipuler des adresses de manire
implicite, en laissant lordinateur gr le principe contenant/contenu. En C++, on dispose pour cela du type rfrence
not type&, utiliser suivant la syntaxe type &reference.
Ainsi, hormis lors de linitialisation, on manipule un contenu et pas un contenant ( linstar des pointeurs). Ce qui
implique quune variable rfrence doit tre initialise la dclaration, et que cette initialisation correspond le plus
souvent une variable dj dclare ; les 2 variables utilisent alors le mme espace mmoire.
Ce type permet notamment de crer une variable synonyme dune autre : la modification de lune delles modifie
automatiquement lautre.
Ex. : int i = 6;

int& j = i;

// dfinition d'une variable rfrence

i = 3;
cout << j << endl;
j = 11;
cout << i << endl;

2.2.2.9

// affichage: "3"
// affichage: "11"

Allocation de mmoire

Venant supplanter malloc() et free(), on dispose de deux nouveaux oprateurs afin de rserver et de librer la
new
et
delete,

utiliser
suivant
les
syntaxes
mmoire.
Il
sagit
des
oprateurs
pointeur = new type_pointeur / delete pointeur pour une variable, ou pointeur = new
type_pointeur[...] / delete[] pointeur lorsque lon dclare plusieurs espaces mmoires contigus.
Ex. : int* ptr;

float* ptr2;
ptr = new int;
// rservation de l'espace mmoire pour 1 int
ptr2 = new float[5];
// rservation de l'espace mmoire pour 5 float
...
delete ptr;
// libration de l'espace mmoire rserv pour 1 int
delete[] ptr2;
// libration de l'espace mmoire rserv pour 5 float

Tout comme malloc(), loprateur new retourne ladresse de dbut du pointeur.


Nb : Les oprateurs new et delete servent galement pour la gestion de lespace mmoire ncessaire aux objets.

13 / 104

Programmation Oriente Objet > Langage C++ > Cours

2.2.3

v1.5.4.2 27/05/2010

Fonctions

2.2.3.1

Paramtres par dfaut

Pour une fonction, il est possible de dfinir des paramtres par dfaut ; cest--dire, spcifier une valeur par dfaut
pour un ou plusieurs paramtres dentre. Il suffit pour cela dinclure, dans le prototype de la fonction, linitialisation
du ou des paramtres leur valeur respective par dfaut.
Pour affecter au paramtre sa valeur par dfaut, il suffit de lomettre dans lappel de la fonction ; sinon cest la
valeur passe en paramtre qui est utilise. Lappel de la procdure peut alors tre ralise de plusieurs manires.
Ex. : void AfficherValeurs(int val1, int val2 = 5)
{

cout << val1 << " " << val2 << endl;
}
int main(void)
{
AfficherValeurs(11, 3);
AfficherValeurs(11);
return 0;
}

// affichage: "11 3"


// affichage: "11 5"

Les paramtres ayant une valeur par dfaut doivent tre positionns la fin de la liste des paramtres du prototype.

2.2.3.2

Fonctions inline

Pour une fonction de petite taille , devant tre appele souvent, on peut dfinir une pseudo-fonction (/macro),
appele fonction inline, afin doptimiser son excution. Pour cela, on utilise le modificateur inline dans la dfinition
du prototype de la fonction.
Ex. : inline int Carre(int n)
{

return n*n;
}
int main(void)
{
cout << Carre(3) << endl;
return 0;
}

// identique cout << 3*3 << endl;

Une fonction inline nest pas compile : le prprocesseur remplace lappel de la fonction par son code source avant
la compilation, vitant ainsi le branchement et la mise en pile raliss normalement lors de lappel dune procdure,
do le gain dexcution.
Nb : Lors de la compilation, le compilateur a toute libert de dcider si effectivement les fonctions dclares
inline seront traites comme telles, ou bien comme des fonctions classiques.

2.2.3.3

Utilisation des rfrences

En plus du passage par valeur, et par adresse (pointeur), on dispose en C++ du passage par rfrence. Lintrt est
de pouvoir travailler dans une fonction avec exactement la mme variable que celle passe en paramtre, en utilisant
pour cela une rfrence qui cre une variable occupant le mme espace mmoire.
Ex. : Une fonction effectuant la permutation de deux nombres passs en paramtres.
void Permut(int& nb1, int& nb2)
{
int tmp = nb1;
nb1 = nb2;
nb2 = tmp;
}

14 / 104

Programmation Oriente Objet > Langage C++ > Cours

int main(void)
{
int i = 2, j = 9;
Permut(i, j);
cout << i << " - " << j << endl;
return 0;
}

v1.5.4.2 27/05/2010

// affichage: "9 - 2"

Nb : Si le passage par rfrence est choisi (fortement conseill pour les paramtres de grande taille comme les
objets), mais que lon dsire viter toute modification, on prcise alors le modificateur const pour le paramtre pass
par rfrence dans la dfinition du prototype.
Une fonction peut retourner une rfrence la valeur de retour, plutt que la valeur elle-mme. Lintrt est quil
est alors possible, lextrieur de la fonction, de modifier cette valeur de retour 1.
Ex. : int t[5];
int& Nieme(int i)
{
return t[i];
}
int main(void)
{
Nieme(0) = 12;
Nieme(1) = 4;
cout << t[0] << " - " << t[1] << endl;
return 0;
}

2.2.3.4

// affichage: "12 - 4"

Surcharge

La surcharge dune fonction correspond la dfinition de fonctions homonymes mais dont la signature est
diffrente ; la signature dune fonction est caractrise par le nom, le nombre et le type des paramtres 2. Lintrt est
de pouvoir utiliser le mme nom de fonction, avec des paramtres diffrents, pour dfinir des comportements de
principe similaire mais pas identiques en tout point.
Ex. : Une fonction effectuant la somme de plusieurs nombres passs en paramtres.
int Somme(int i1, int i2)
{
return i1 + i2;
}
int Somme(int i1, int i2, int i3)
{
return i1 + i2 + i3;
}
double Somme(double d1, double d2)
{
return d1 + d2;
}

Apparassent ici les notions dentits de type LValue (Left Value (eng) Z Valeur de Gauche (fr)) et RValue (Right Value (eng) Z Valeur de
Droite (fr)) qui prcisent si ce qui reprsente une valeur (variable ou fonction) peut tre positionn gauche ou droite du signe = dans une
expression daffectation. Ainsi, une variable peut tre LValue (ex. : var = 1;) ou RValue (ex. : autrevar = var;) ; une fonction retournant
une valeur ou un pointeur peut tre RValue (ex. : x = fonction();), mais ne peut en aucune manire tre LValue
(ex. : int fonction(); fonction() = 1; // erreur d'excution) ; en revanche, une fonction retournant une rfrence peut tre
RValue, mais aussi LValue (ex. : int& fonction(); fonction() = 1; // pas d'erreur dexcution).
Rappels : le prototype dune fonction est caractrise par le nom, le nombre et le type des paramtres, ainsi que le type de valeur de retour ;
donc, prototype Z signature + type de valeur de retour.
15 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

int main(void)
{
int i = 2, j = 4, k = 8;
double x = 4.32, y = -51.3;
cout << Somme(i, j) << endl;
cout << Somme(x, y) << endl;
cout << Somme(i, j, k) << endl;
return 0;
}

Cest le compilateur qui se charge de slectionner la fonction excuter en comparant les signatures de la fonction
appele et des diffrentes fonctions surcharges existantes.

16 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

3 LES OBJETS ET LES CLASSES


3.1 LA PROGRAMMATION ORIENTE OBJET
3.1.1

Lapproche objet

La programmation procdurale, dite aussi fonctionnelle 1, se base sur lanalyse descendante des fonctions attendues
du systme avec un processus rcursif de dcoupage en sous-fonctions de plus en plus faciles apprhender, et ce,
jusqu atteindre un niveau de codage ralisable. Lanalyse est donc uniquement axe sur ce que fait le systme.
Lapproche objet consiste considrer le systme comme un ensemble dlments organiss qui interagissent afin
de constituer un tout : le systme est fait dobjets qui collaborent par lintermdiaire de messages. Lanalyse est axe
sur ce quest le systme et comment est organis le systme, en plus de ce que fait le systme. Ce type danalyse,
appele aussi approche systmique, a pour but de reprsenter au mieux le monde rel dans lequel voluent les
systmes informatiques et rpondre ainsi plus aisment aux besoins.
La Programmation Oriente Objet, qui met en uvre lapproche objet, date des annes 60, et de nombreux langages
objets ou orients objet ont t crs 2 afin de rpondre au mieux ses diffrents principes. Elle est en plein essor
depuis une quinzaine dannes, et est devenue incontournable dans lindustrie de dveloppement de produits logiciels,
pour les nombreux avantages quelle propose.

3.1.2

Atouts

Lapproche objet, de par ses principes, sinsre dans une dmarche de qualit, dans le but de fournir des mthodes et
outils pour crer des produits logiciels plus performants suivant diffrents axes : maniabilit, maintenabilit,
testabilit, lisibilit, modularit, interoprabilit, portabilit, robustesse, extensibilit, volutivit, rutilisabilit.
Elle est adapte quasiment tous les champs dinvestigation de la programmation, notamment car elle propose une
technologie plus proche de la ralit, ainsi quune mthodologie accre ; en revanche, elle demande un effort
supplmentaire dabstraction et de conceptualisation.

3.2 LOBJET
3.2.1

Introduction : rappels sur les structures

Une structure est un type de donnes utilisateur qui permet de regrouper des variables de diffrents types en un
seul ensemble. Chaque variable au sein de la structure, appele champ, est accessible indpendamment des autres.
Une structure dfinit un nouveau type, cest--dire un modle de variables, utilisable comme les types de variables
classiques . Ce modle de variables permet ainsi de crer des variables possdant les champs dfinis (nom et type).
Ex. : Soit une structure, constitue de 2 champs, reprsentant une personne, nomme Personne.
Personne
age : int
initiale : char

Figure 3.1 : exemple de structure

1
2

Langage C, par exemple.


Sans ordre particulier : C++, Java, SmallTalk (lun des tout premiers), ADA, PHP5, Delphi, C#,
17 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Lorsque lon fait rfrence lun des champs dune structure, il faut obligatoirement prfixer le nom du champ par
le nom de la structure laquelle il appartient. Pour cela, on utilise loprateur . (point) ou -> (tiret + suprieur),
suivant la syntaxe variable_structuree.champ / variable_structuree->champ.
Une fois dclare, une variable structure peut tre utilise de diverses manires :
V On utilise lun des champs de la structure : il se manipule comme une variable classique, est du type dfini
lors de la dfinition de la structure, et doit tre prfix du nom de la variable structure.
Ex. : Soit eleve une variable structure de type Personne ; pour accder chacun des champs initiale et
age, on crira respectivement eleve.initiale et eleve.age.
V On utilise la variable structure dans son ensemble (ce qui sous-entend aussi la totalit des champs de la

structure) : elle se manipule comme une variable classique, est du type du nom de la structure, et peut tre
passe comme paramtre dentre dune fonction ou comme type de retour dune fonction ; tous les champs
et leur valeur sont ainsi inclus .
Ex. : Soit eleve une variable structure de type Personne ; pour manipuler la variable structure et donc
ainsi lensemble des champs, on crit simplement eleve.

3.2.2

Dfinitions

Selon le dictionnaire en ligne Mediadico 1, la dfinition du mot objet est la suivante :


Objet (n.m.) i. Ce qui affecte les sens.
ii. Ce qui se prsente lesprit.
iii. Chose dans un sens indtermin.
En informatique, le terme objet est tout aussi large, et dsigne une entit informatique qui reprsente de manire
abstraite une entit concrte ou abstraite du monde rel ou virtuel 2, dans le but de la piloter ou de la simuler. Cette
reprsentation abstraite est une image simplifie de lobjet originel effectivement reprsent, en ne conservant que les
composantes intrinsques ncessaires une problmatique donne 3.
Un objet peut ainsi tre dfini par trois caractristiques :
V un tat : ce quest lobjet, ensemble des valeurs instantanes de toutes les informations qualifiant lobjet
(appeles attributs) ; cest laspect statique ;
V un comportement : ce que peut faire lobjet, ensemble des comptences de lobjet ainsi que de ses actions et
ractions (appeles mthodes) ; cest laspect dynamique ;
V une identit : concept caractrisant lexistence propre dun objet hors de toute considration dtat et de
comportement.
On pourrait ainsi crire : objet L tat + comportement + identit, en insistant sur le fait que lobjet ainsi dfini est
plus que la somme de ses 3 caractristiques 4.
Ex. : Soit un objet reprsentant un vhicule du monde rel.
Ltat du vhicule peut tre dfini par diverses informations : marque, modle, couleur,
Le comportement du vhicule peut tre dfini par diverses comptences et actions/ractions : dmarrer, arrter,
acclrer, freiner,
Lidentit du vhicule permet de faire la distinction entre 2 vhicules de mmes marque, modle et couleur
mais qui ont pourtant 2 existences propres (mme sils sont pareils en tout point, chacun deux est unique ; par
exemple, si lun est abm lors dun accident, cela naura aucune rpercussion sur lautre).

3.2.3

Principes de classe et d instance de classe

Tout objet appartient une famille dobjets, appele classe. Une classe symbolise un ensemble dobjets ayant un
tat similaire (mmes informations, mais pas forcment de mme valeur) et un comportement identique.
Ce terme dsigne donc un modle dobjets, tel un type de variables classique ou bien une structure, qui permet de
crer des objets didentit diffrente, mais dtat similaire, et de comportement identique.

1
2
3
4

http://www.mediadico.com.
La notion d objet informatique est donc aussi vague que la notion usuelle d objet .
La reprsentation informatique dun mme objet (au sens usuel du terme) peut ainsi tre trs diffrente dune application une autre.
limage de la maxime le tout vaut plus que la somme des parties .
18 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ltat et le comportement de tout objet sont donc bass sur ceux de la classe dont il provient : lobjet est une
instance dune classe, i.e. une copie fabrique sur le modle dune classe, avec une identit propre, un tat de mme
nature mais avec ses valeurs spcifiques, et un comportement commun tous les objets dune classe.
classe

instance
copie

Figure 3.2 : classe et instance de classe

Lobjet (ou instance) est manipulable alors que la classe reste un modle immuable. De fait, un objet peut tre cr,
utilis et dtruit, alors que la classe ne peut tre quutilise comme modle.
Pour reprsenter une classe, on utilise gnralement une reprsentation type UML sous forme de cadre avec
plusieurs sparateurs pour prciser : nom de la classe, liste des attributs (tat), liste des mthodes (comportement).
NomClasse
attributs

tat

Methodes

comportement

Figure 3.3 : reprsentation UML dune classe

Ex. : Soit la classe Vehicule reprsentant la notion de vhicule du monde rel.


Vehicule
couleur
marque
modele
Accelerer
Arreter
Demarrer

Figure 3.4 : exemple dune classe

Sur ce modle, pourront tre crs divers objets Vehicule : une voiture de couleur bleue de marque SuperCar
et de modle Sonic, un vlo de couleur rouge de marque KoolBk et de modle Mud, un camion de couleur
noire de marque BigTruck et de modle 40Tons, etc. ; ces vhicules peuvent acclrer, dmarrer, et sarrter ;
ces vhicules sont diffrents lun de lautre. Par consquent, ils ont chacun leur identit propre, un tat
parfaitement dfini, et un comportement identique.
classe

instances

Vehicule

voiture

tat:
<couleur>
<marque>
<modle

tat:
bleu
SuperCar
Sonic

comportement:
Acclrer
Arrter
Dmarrer

copie

copie

comportement:
Acclrer
Arrter
Dmarrer

velo
tat:
rouge
KoolBk
Mud
comportement:
Acclrer
Arrter
Dmarrer

Figure 3.5 : exemple de cration dinstances diffrentes partir dune mme classe
19 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

En passant la reprsentation informatique dune famille dobjets, les attributs dune classe (tat) sont reprsents
par des variables, et les mthodes dune classe (comportement) par des fonctions. Le terme classe dsigne donc
une entit informatique spcifique regroupant des variables associes et des fonctions associes en un seul ensemble ;
le terme de membres dsigne lensemble des attributs et des mthodes de cette classe.
Ex. : Soit la classe Vehicule reprsentant la notion de vhicule du monde rel.
Vehicule
couleur : int
marque : char*
modele : char*
Accelerer() : void
Arreter() : void
Demarrer() : void

Figure 3.6 : exemple dune classe avec dtail des attributs et mthodes

Par la suite, laccs aux divers membres dune instance dune classe sopre de manire identique aux structures :
V oprateur . (point) pour une instanciation classique (statique) (Ex. : monVehicule.couleur et
monVehicule.Demarrer()) ;
V oprateur -> (tiret + suprieur) pour une instanciation laide dun pointeur (dynamique) (Ex. :
monVehicule->couleur et monVehicule->Demarrer()).
Il est noter quun membre na de sens que lorsquil est associ un objet de la classe laquelle il appartient. Par
consquent, deux membres ayant mme nom mais appartenant deux classes distinctes nont aucun lien entre eux 1.

3.2.4

Principe d encapsulation

Lapproche objet amne de la cohrence et de la prcision dans la dfinition des modles 2 utiliss. La cohsion
interne dun objet est notamment trs forte, et doit tre protge de lextrieur ; cependant, lobjet doit proposer un
ensemble de services afin dinteragir avec son environnement : cest ce quon appelle lencapsulation 3.
Il convient donc de prserver la valeur des attributs dun objet, en leur donnant le caractre (littralement) priv, ce
qui interdit tout accs de lextrieur de la classe, que ce soit en lecture ou en criture.
En revanche, il faut permettre lobjet de collaborer avec dautres objets, et on donne alors aux mthodes le
caractre public, ce qui autorise leur appel de lintrieur comme de lextrieur de la classe.
Sil est ncessaire de permettre laccs aux attributs de lextrieur de la classe, il faut donc utiliser les mthodes de
la classe, qui assureront ainsi des accs contrls par la classe elle-mme.
Ce caractre public/priv, appel visibilit 4 ou droit daccs, peut tre adapt si besoin ; nanmoins, par dfaut, afin
de respecter lencapsulation, les attributs doivent donc tre privs, et les mthodes publiques.
Dans la reprsentation de la classe (reprsentation UML), un caractre public est symbolis par lajout dun + (plus)
devant le nom du membre, alors quun caractre priv est symbolis par lajout dun (moins).
Ex. : Soit la classe Vehicule reprsentant la notion de vhicule du monde rel.
Vehicule
- couleur : int
- marque : char*
- modele : char*
+ Accelerer() : void
+ Arreter() : void
+ Demarrer() : void

Figure 3.7 : exemple dune classe avec dtail des attributs et mthodes, et de leur visibilit

Lensemble des membres publics est appel interface de la classe, car vu de lextrieur, ils en reprsentent la partie
merge, alors que la partie immerge (les membres non publics 5) reste totalement inconnue.
Nb : Les membres non-publics ne sont protgs que de lextrieur de la classe ; cette protection na pas cours pour
deux objets distincts de la mme classe. On parle dencapsulation de classe et non dencapsulation dobjet.
1
2
3
4
5

Exemple : La mthode Demarrer() de la classe Vehicule fait tout autre chose que la mthode Demarrer() de la classe Ordinateur.
Les classes.
Lencapsulation est avec lhritage et le polymorphisme lun des principes dfinissant la Programmation Oriente Objet (cf. annexe D).
Il existe un troisime caractre de visibilit, protg, qui dfinit un accs restreint la classe et aux classes hrites (cf. 5.1.1).
Membres privs et protgs.
20 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

3.3 CRITURE DUNE CLASSE


3.3.1

Dclaration dune classe

Avant dutiliser un objet, il faut donner la dclaration de la classe laquelle appartient cet objet. Cette dclaration
correspond la description de ltat et du comportement de la classe :
V tat : nom, type, et visibilit de chaque attribut ;
V comportement : prototype et visibilit de chaque mthode.
On dclare alors la classe en utilisant le mot-clef class en regroupant ses diffrents membres par visibilit 1
(membres publics : public, membres privs : private), suivant la syntaxe :
class NomClasse // nom de la classe dbute par une majuscule
{
public:
type_mthode1 NomMethode1(type_paramtre1-1, type_paramtre1-2, ...);
type_mthode2 NomMethode2(type_paramtre2-1, type_paramtre2-2, ...);
...
private:
type_attribut1 nomAttribut1;
type_attribut2 nomAttribut2;
...
}; // attention ne pas oublier le ; final !

Nb : Si un membre est dclar hors dune catgorie de visibilit (au tout dbut), il est considr comme tant priv.
Ex. : Soit une classe reprsentant une personne.
Personne
- age : int
- nom : char*
+ AfficherInfos() : void

Figure 3.8 : exemple de dclaration dune classe


class Personne
{
public:
void AfficherInfos();
private:
int age;
char* nom;
};

Nb : La dclaration dune classe est gnralement ralise dans un fichier den-tte, portant lextension .h, dont le
nom est le nom exact de la classe (Ex. : Personne.h).

3.3.2

Implmentation des mthodes

Les mthodes peuvent tre dfinies dans la dclaration de la classe elle-mme 2, telles de simples fonctions, mais en
rgle gnrale leur implmentation (criture du code de la mthode) est donne lextrieur. Pour savoir que la
mthode appartient la dfinition dune classe, et quelle classe 3, on prfixe alors le nom de la mthode avec le nom
de la classe, suivi de loprateur de rsolution de porte :: (2x deux-points), suivant la syntaxe
type_mthode NomClasse::NomMethode(type_paramtre1 nomParametre1, ...).
Ex. : La mthode AfficherInfos() de la classe Personne.
void Personne::AfficherInfos() // nom d'une mthode dbute par une majuscule
{
...
}

1
2
3

On ordonne gnralement les catgories de visibilit en commenant par la catgorie public.


Elles sont alors considres par le compilateur comme des fonctions inline (cf. 2.2.3.2).
Et nest donc pas une simple fonction.
21 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Le corps de dfinition dune mthode appartient la classe. En consquence, on accde librement nimporte quel
membre de la classe, mme les membres privs ; de plus, il est inutile de prfixer leur nom.
Ex. : Les mthodes de la classe Personne.
void Personne::AfficherInfos()
{
cout << "age " << age << endl;
cout << "nom " << nom << endl;
}

Nb : Limplmentation des mthodes membres est gnralement ralise dans un fichier spar du fichier den-tte,
portant lextension .cpp, dont le nom est le nom exact de la classe (Ex. : Personne.cpp).

3.3.3

Principe de constructeur

Un objet est linstance dune classe, cest--dire une entit cre sur le modle dune classe, qui possde une
existence propre (identit) et un tat dfini, en sus du comportement commun tous les objets de la classe.
Lors de la dclaration dun objet (NomClasse nomObjet;), lidentit est cre (nomObjet est fabriqu sur le
modle NomClasse), et les mthodes sont pleinement dfinies (reprises directement de la dfinition de la classe).
En revanche, mme si les attributs sont dfinis, ils ne sont pas initialiss et ne possdent pas de valeurs spcifiques
lobjet reprsent. Il faut donc mettre en place un mcanisme dinitialisation des attributs.
Pour raliser cela, on va utiliser une mthode, appele constructeur, qui a en charge dinitialiser tous les attributs de
lobjet. Cette mthode spcifique a pour particularits :
V nom exactement identique au nom de la classe (NomClasse(...)) ;
1
V mthode publique (pour pouvoir tre appele de lextrieur de la classe ) ;
V aucun type de retour (pas mme void) ;
V a ou pas des paramtres dentre, pouvant servir initialiser les attributs des valeurs externes la mthode.
Lorsque le constructeur peut tre appel sans paramtre (constructeur sans aucun paramtre, ou dont chaque
paramtre possde une valeur par dfaut), on parle de constructeur par dfaut.
Nb : Au-del de linitialisation des attributs, le constructeur peut aussi effectuer toutes sortes dinitialisations
ncessaires la cration dun objet.
Ex. : Le constructeur par dfaut de la classe Personne.
Personne
- age : int
- nom : char*
+ Personne()
+ AfficherInfos() : void

Figure 3.9 : exemple dune classe avec un constructeur par dfaut


class Personne
{
public:
Personne(); // constructeur par dfaut
void AfficherInfos();
private:
int age;
char* nom;
};
Personne::Personne()
{
age = 0;
nom = new char[10];
nom = "johndoe"; // nda : John Doe est l'quivalent anglais de M. Dupont ou
}
// Durand pour dsigner une personne de nom inconnu
1

Puisque pour appeler une mthode comme le constructeur de lintrieur de la classe, il faut disposer dun objet complet, donc ayant un tat
pleinement dfini, lequel ne peut tre ralis que grce au constructeur ! (nda : cf. paradoxe de luf et de la poule).
22 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

En ce cas, lors de la simple dclaration dun objet, un appel implicite au constructeur par dfaut est ralis. Lobjet
est donc parfaitement instanci.
Ex. : Personne eleve1;

// un objet eleve1 de la classe Personne est dclar


// et instanci par appel implicite au constructeur par dfaut

Le terme dinstanciation induit donc en ralit les actions suivantes :


V dclarer un nouvel objet : nom de lobjet + nom de sa classe (/type) ;
V rserver lespace mmoire ncessaire au stockage de lobjet (soit implicitement lors dune dclaration en
statique, soit explicitement lors dune dclaration dynamique) ;
V initialiser les attributs de lobjet : appel au constructeur.
Nb : Un constructeur ne peut tre appel que lors de linstanciation dun objet, et ne peut donc tre appel si lobjet
est dj instanci.
Puisque le constructeur peut avoir ou pas des paramtres dentre, il peut donc tre surcharg comme toute mthode.
Ex. : Surcharges du constructeur de la classe Personne.
Personne
- age : int
- nom : char*
+
+
+
+

Personne()
Personne(int)
Personne(int, char*)
AfficherInfos() : void

Figure 3.10 : exemple dune classe avec plusieurs constructeurs


class Personne
{
public:
Personne(); // constructeur par dfaut
Personne(int); // surcharge du constructeur
Personne(int, char*);
// autre surcharge du constructeur
void AfficherInfos();
private:
int age;
char* nom;
};
Personne::Personne()
{
age = 0;
nom = new char[10];
nom = "johndoe";
}
Personne::Personne(int a)
{
age = a;
nom = new char[10];
// rservation de l'espace mmoire ncessaire
nom = "johndoe";
}
Personne::Personne(int a, char* n)
{
age = a;
nom = new char[strlen(n)+1];
// rservation de l'espace mmoire ncessaire
strcpy(nom, n);
// recopie de la chane passe en paramtre dans l'attribut
}

Pour instancier un objet, on dispose alors de plusieurs constructeurs, et de plusieurs formes (appel implicite /
explicite du constructeur).

23 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : Personne eleve1;


Personne
Personne
Personne
Personne
Personne

// appel implicite au constructeur par dfaut


1
eleve2 = Personne();
// appel explicite au constructeur par dfaut
eleve3(20);
// appel implicite au constructeur 1 paramtre (int)
eleve4 = Personne(19);
// appel explicite au constructeur 1 paramtre
eleve5(30, "joe");
//appel implicite au constructeur 2 paramtres
eleve6 = Personne(22, "bob"); // appel explicite au constructeur 2
// paramtres

Dans le cas de la dclaration dun pointeur sur un objet, le constructeur ne peut jamais tre appel implicitement, il
faut donc le faire explicitement pour raliser une instanciation complte.
Ex. : Personne* eleve7;
Personne* eleve8;
Personne* eleve9;

eleve7 = new Personne;


eleve8 = new Personne();
eleve9 = new Personne(15);

// dclaration d'un objet de la classe Personne


// dclaration d'un objet de la classe Personne
// dclaration d'un objet de la classe Personne
// appel explicite au constructeur par dfaut
// appel explicite au constructeur par dfaut
// appel explicite au constructeur 1 paramtre

Personne* eleve10 = new Personne(16); // instanciation d'un objet Personne


Personne* eleve11 = new Personne(28, "ken"); // instanciation d'un objet Personne

Si on ne spcifie aucun constructeur dans la dfinition de la classe, le compilateur en gnre automatiquement un 2,


qui est le constructeur par dfaut, initialisant ainsi tous les attributs de la classe.
En revanche, ds quun constructeur est dfini, que celui-ci soit par dfaut ou non, le compilateur nen gnre
aucun 3 ; il faut donc crire explicitement le constructeur par dfaut si lon en a besoin.
Le constructeur par dfaut est notamment ncessaire pour toute dclaration dun tableau dobjets. Nanmoins, dans
le cas dun tableau statique, il est possible de spcifier explicitement linitialisation de chacun des objets du tableau via
un appel lune des surcharges du constructeur (nda : solution inadquate pour des tableaux de grande taille).
Ex. : Personne groupe1Eleves[2];

// appel implicite au constructeur par dfaut


Personne groupe2Eleves[2] = { Personne(30, "joe"),
// appels explicites au
Personne(22) };
// constructeur
Personne* groupe3Eleves = new Personne[2];
// appel explicite au constructeur
// par dfaut

Nb : Lusage des valeurs par dfaut pour les paramtres des constructeurs permet de faire correspondre plusieurs
surcharges 1 seul constructeur. Si on spcifie un constructeur avec une valeur par dfaut pour chacun des paramtres,
celui-ci correspond donc, entre autres, au constructeur par dfaut.
Ex. : Un constructeur de la classe Personne avec des valeurs par dfaut pour tous les paramtres.
Personne
- age : int
- nom : char*
+ Personne(int = 0, char* = "johndoe")
+ AfficherInfos() : void

Figure 3.11 : exemple dune classe avec un constructeur avec des valeurs par dfaut pour tous les paramtres

On distingue les critures (1) : MaClasse unObjet = MaClasse(); et (2) : MaClasse unObjet; nouvelObjet = MaClasse();. En (1),
on dclare un nouvel objet et on linitialise en effectuant un appel explicite au constructeur (1 construction) ; en (2), on dclare un nouvel
objet, qui est construit grce un appel implicite au constructeur par dfaut, puis on lui affecte une valeur en utilisant un objet anonyme
(cf. 0) construit en effectuant un appel explicite au constructeur par dfaut (2 constructions + 1 affectation). Les rsultats obtenus suivant lune
ou lautre des 2 mthodes sont les mmes mais la mthode (2) est bien plus coteuse en ressources.
Celui-ci nest pas trs volu, et sil permet dinstancier un objet, il est peut-tre inadquat, voire mme peu pertinent lorsque certains attributs
sont dclars en dynamique (cf. 3.4.1).
Estimant, raison, que vous navez donc pas oubli dcrire un constructeur.
24 / 104

Programmation Oriente Objet > Langage C++ > Cours

class Personne
{
public:
Personne(int = 0, char* = "johndoe");
void AfficherInfos();
private:
int age;
char* nom;
};
...

v1.5.4.2 27/05/2010

// valeurs par dfaut

Personne::Personne(int a, char* n)
// constructeur correspondant Personne(),
{
// Personne(int) et Personne(int, char*)
age = a;
nom = new char[strlen(n)+1];
// rservation de l'espace mmoire ncessaire
strcpy(nom, n);
// recopie de la chane passe en paramtre dans l'attribut
}

3.3.4

Principe de destructeur

De la mme manire quun mcanisme est mis en uvre la cration dun objet afin de linitialiser (constructeur),
un mcanisme spcifique est mis en uvre la destruction de lobjet.
Pour cela on dispose dune mthode, appele destructeur, qui a en charge de raliser diverses oprations avant la
destruction finale de lobjet (vidage des buffers, libration mmoire, etc.). Cette mthode spcifique a pour
particularits :
V nom presque identique au nom de la classe, mais prfixe de ~ (tilde) (~NomClasse()) ;
V mthode publique (pour pouvoir tre appele de lextrieur de la classe) ;
V aucun type de retour (pas mme void) ;
V aucun paramtre dentre (ne peut donc tre surcharge).
Le destructeur est appel implicitement lors de la destruction dun objet (fin du bloc de code de dclaration pour une
instanciation statique, utilisation de loprateur delete 1 en cas dinstanciation dynamique). Mme si cela est
possible, il nest gnralement pas appel explicitement.
L aussi, si on ne spcifie aucun destructeur dans la dfinition de la classe, le compilateur en gnre
automatiquement un.
Ex. : Le destructeur de la classe Personne.
Personne
- age : int
- nom : char*
+ Personne(int = 0, char* = "johndoe")
+ ~Personne()
+ AfficherInfos() : void

Figure 3.12 : exemple dune classe avec destructeur


class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
// destructeur
void AfficherInfos();
private:
int age;
char* nom;
};
...

Ou accessoirement, fin de lexcution du programme si on fait confiance au systme dexploitation et au gestionnaire de mmoire.
25 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Personne::~Personne()
{
delete[] this->nom;
}

3.3.5

Le pointeur this

Tout membre (attribut ou mthode) appartient un objet, donc lorsque lon dsire faire appel un membre dune
classe, il faut imprativement prciser le nom de lobjet auquel appartient le membre dsign.
Or, dans limplmentation dune mthode, laccs aux attributs, ainsi quaux autres mthodes de la classe, peut se
faire directement, sans prfixer avec le nom de lobjet ; en effet, le nom de lobjet est induit car on se trouve dans
la classe 1.
Cependant, il est possible, et mme conseiller, de spcifier explicitement que le membre utilis appartient bien la
classe, et nest donc pas quune simple variable ou fonction.
Pour cela, il faut utiliser un paramtre cach disponible dans toute mthode de la classe, le pointeur this, qui fait
rfrence lobjet lui-mme 2. Il est implicitement dclar NomClasse* const this, et sutilise suivant la syntaxe
3
this->nom_membre pour accder au membre.
Ex. : Un constructeur de la classe Personne.
Personne::Personne(int a, char* n)
{
this->age = a;
this->nom = new char[strlen(n)+1];
strcpy(this->nom, n);
this->AfficherInfos();
// affichage des informations
}

3.3.6

Les mthodes accesseurs

Les attributs sont thoriquement protgs grce lencapsulation qui empche tout accs de lextrieur de la classe.
Nanmoins, il peut parfois tre utile daugmenter les capacits de la classe interagir avec son environnement. Pour
raliser cela, on dispose dun mcanisme spcifique via des mthodes particulires.
Les mthodes accesseurs sont des mthodes permettant daccder aux attributs dune classe partir de lextrieur,
sans violer lencapsulation. chaque attribut, on peut ainsi faire correspondre 2 mthodes accesseurs :
V laccesseur en lecture : mthode permettant de connatre la valeur dun attribut partir de lextrieur de la
classe, de prototype usuel type_attribut GetAttribut() 4 ;
V laccesseur en criture : mthode permettant de modifier la valeur dun attribut partir de lextrieur de la
classe, de prototype usuel void SetAttribut(type_attribut) 5.
Pour chaque attribut, on crit donc les accesseurs ncessaires (lecture et/ou criture) en fonction des besoins.
Nb : Les accesseurs lecture/criture peuvent aussi tre appels accesseurs/mutateurs ou getteurs/setteurs.
Ex. : Les accesseurs de lattribut age.
Personne
- age : int
- nom : char*
+
+
+
+
+

Personne(int = 0, char* = "johndoe")


~Personne()
AfficherInfos() : void
GetAge() : int
SetAge(int) : void

Figure 3.13 : exemple dune classe avec les accesseurs dun attribut

2
3
4
5

Par ailleurs, il serait impossible de spcifier le nom de lobjet, car plusieurs objets dont on ne peut connatre le nom lavance seront
certainement crs partir de cette classe.
This (eng) celui-ci (fr).
this tant un pointeur de type NomClasse*, il faut donc utiliser -> (tiret+flche) pour accder au membre, et non pas . (point).
To get (eng) obtenir (fr).
To set (eng) rgler (fr).
26 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
void AfficherInfos();
int GetAge();
// accesseur en lecture pour l'attribut age
void SetAge(int);
// accesseur en criture pour l'attribut age
private:
int age;
char* nom;
};
...
int Personne::GetAge()
{
return this->age;
}
void Personne::SetAge(int a)
{
this->age = a;
}

Nb : Lorsquun attribut possde un getteur et un setteur associs, celui-ci est alors pleinement accessible de
lextrieur de la classe. Nanmoins, cela demeure diffrent dune visibilit publique car les accesseurs peuvent
contrler ses accs et ses modifications (Ex. : viter une valeur dcriture errone, transmettre une valeur de lecture
mise lchelle, etc.).
Ex. : La mthode SetAge() de la classe Personne.
void Personne::SetAge(int a)
{
if ( a >= 0 ) this->age = a;
}

// vrification sur l'affectation de l'attribut

3.4 COMPLMENTS
3.4.1

Constructeur de recopie

Lors de linstanciation dun objet, on peut se baser sur un objet existant de la mme classe pour en crer un nouveau,
tel une recopie. La valeur de chaque attribut est alors simplement copie dun objet lautre. On dispose pour cela des
2 syntaxes NomClasse nouvelObjet = ancienObjet ou NomClasse nouvelObjet(ancienObjet).
Ex. : Personne* eleve10 = new Personne(16);
Personne eleve12 = *eleve10;
Personne eleve13(*eleve10);

// instanciation d'un objet


// instanciation d'un objet partir d'un autre
// idem (syntaxe raccourcie)

Si ces syntaxes fonctionnent trs bien pour de nombreuses classes, ce nest pas le cas de classes possdant des
attributs allous dynamiquement ; dans ce cas, ce nest pas la valeur pointe qui est recopie, mais la valeur de
ladresse. Les objets ainsi recopis, voulus indpendants, ont des attributs communs ils possdent chacun un
attribut distinct allou en dynamique pointant sur un mme espace mmoire , ce qui sous-entend que toute
modification sur la valeur de cet attribut partir dun objet, se rpercute sur lautre objet.
Cet effet de bord est rarement dsir 1, dautant plus que si lun des objets est dtruit, tous ses attributs aussi ; lautre
objet possde donc un attribut pointant sur un espace mmoire qui a t libr (nda : erreur dexcution en prvision !).
Ex. : Copie dun objet Personne partir dun autre objet Personne.

Pour disposer dun attribut commun plusieurs objets, on se tournera alors ventuellement vers la dfinition dun attribut statique (cf. 3.4.3).
27 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Personne
- age : int
- nom : char*
+
+
+
+
+

Personne(int = 0, char* = "johndoe")


~Personne()
AfficherInfos() : void
SetAge(int) : void
SetNom(char*) : void

Figure 3.14 : exemple dune classe sans constructeur de recopie


class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
void AfficherInfos();
void SetAge(int);
void SetNom(char*);
private:
int age;
char* nom;
};
...
void Personne::SetNom(char* n)
{
delete[] this->nom;
// destruction de l'ancienne version de l'attribut
this->nom = new char[strlen(n)+1];
strcpy(this->nom, n);
}
int main(void)
{
Personne* eleve10 = new Personne(16);
Personne eleve12 = *eleve10; // eleve12 est une copie de eleve10
eleve10->AfficherInfos(); // affichage: "16" | "johndoe"
eleve12.AfficherInfos(); // affichage: "16" | "johndoe"
eleve10->SetAge(20);
eleve10->SetNom("tim"); // modification de l'attribut nom de l'objet eleve10
eleve10->AfficherInfos();
// affichage: "20" | "tim"
eleve12.AfficherInfos(); // affichage: "16" | "tim" -> eleve12 a t modifi!
// la modification sur l'objet eleve10 modifie aussi l'objet eleve12
delete eleve10; // destruction de l'objet eleve10
eleve12.AfficherInfos(); // affichage: "16" | "" -> eleve12 a t modifi!
// la destruction de l'objet eleve10 a dtruit l'un des attributs de eleve12
return 0;
}

En ralit, pour linstanciation dun objet partir dun autre dj instanci 1, le compilateur utilise bien un
constructeur comme pour toute instanciation, mais un constructeur spcifique au clonage inter-objets, appel
constructeur de recopie.
linstar du constructeur par dfaut, si un constructeur de recopie nest pas explicitement crit, alors le compilateur
en gnre automatiquement un, qui, comme il a t observ, trouve rapidement ses limites.
Le constructeur de recopie est ainsi appel lors de linstanciation dun nouvel objet partir dun objet dj
instanci ; mais il est aussi utilis de manire cache dans 2 cas trs importants lors de lappel de toute mthode :
2
V lors dun passage par valeur dun paramtre de type objet (le paramtre-objet est clon) ;
1
21
V lors dun renvoi par valeur dun objet (lobjet renvoy est clon) .
1
2

laide de la syntaxe NomClasse nouvelObjet = ancienObjet ou NomClasse nouvelObjet(ancienObjet).


Ce qui explique notamment que lobjet dans la mthode et lobjet correspondant lextrieur de la mthode soient diffrents : lun a t clon
pour obtenir lautre.
28 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Pour dfinir la manire dont un objet est copi partir dun autre, il suffit donc dcrire le constructeur de recopie
qui a comme prototype gnrique : NomClasse(const NomClasse&) 2.
Ex. : Le constructeur de recopie de la classe Personne.
Personne
- age : int
- nom : char*
+
+
+
+
+
+

Personne(int = 0, char* = "johndoe")


Personne(const Personne&)
~Personne()
AfficherInfos() : void
SetAge(int) : void
SetNom(char*) : void

Figure 3.15 : exemple dune classe avec constructeur de recopie


class Personne
{
public:
Personne(int = 0, char* = "johndoe");
Personne(const Personne&);
// constructeur de recopie
~Personne();
void AfficherInfos();
void SetAge(int);
void SetNom(char*);
private:
int age;
char* nom;
};
...
Personne::Personne(const Personne& p)
{
this->age = p.age;
// recopie de la valeur
this->nom = new int[strlen(p.nom)+1]; // nouvelle rservation d'espace mmoire
strcpy(this->nom, p.nom);
// recopie de la chane
}
int main(void)
{
Personne* eleve10 = new Personne(16);
Personne eleve12 = *eleve10; // eleve12 est une copie de eleve10
eleve10->AfficherInfos(); // affichage: "16" | "johndoe"
eleve12.AfficherInfos(); // affichage: "16" | "johndoe"
eleve10->SetAge(20);
eleve10->SetNom("tim");
// modification de l'attribut nom de l'objet eleve10
eleve10->AfficherInfos();
// affichage: "20" | "tim"
eleve12.AfficherInfos(); // affichage: "16" | "johndoe" -> eleve12 inchang
// la modification sur l'objet eleve10 ne modifie pas l'objet eleve12
delete eleve10; // destruction de l'objet eleve10
eleve12.AfficherInfos(); // affichage: "16" | "johndoe" -> eleve12 inchang
// la destruction de l'objet eleve10 ne change rien eleve12 et ses attributs
return 0;
}

Nb : Dans le constructeur de recopie, on peut noter que lobjet this peut accder sans problme aux attributs de
lobjet pass en paramtre, ce qui est possible car les 2 objets font partie de la mme classe, et lencapsulation en C++
est ralise au niveau de la classe, et non au niveau de lobjet 3.
1

Par souci doptimisation, certains compilateurs contournent parfois cet appel au constructeur de recopie : la valeur retourne est positionne
directement en zone de mmoire temporaire accessible au contexte appelant plutt que dans un segment de mmoire spcifique la mthode
pour tre ensuite recopi dans une zone de mmoire temporaire lorsque la mthode se termine (cf. E.2.2).
La syntaxe NomClasse nouvelObjet(ancienObjet), permettant de crer un nouvel objet partir dun autre dj existant, devient alors
vidente.
cf. 3.2.4.
29 / 104

Programmation Oriente Objet > Langage C++ > Cours

3.4.2

v1.5.4.2 27/05/2010

Instanciation et destruction dun attribut-objet

Le rle dun constructeur est dinitialiser les attributs dun objet afin de raliser une instanciation complte.
Lorsquune classe comprend un attribut de type objet 1, celui-ci doit tre pleinement instanci pour pouvoir instancier
un objet de la classe. Autrement dit, linstanciation dun objet dune classe suppose et impose que ses attributs-objets 2
soient eux aussi instancis ; cette instanciation est ralise juste avant linstanciation de lobjet.
De la mme manire, le destructeur, qui a en charge deffectuer proprement la destruction des attributs, soccupe de
dtruire les attributs-objets tout de suite aprs la destruction de lobjet lui-mme.
ClasseB

ClasseA
monB : ClasseB

ClasseA

plus gnralement
not ainsi :

monB

ClasseB

Figure 3.16 : reprsentation dune classe avec un attribut de type objet

Ces mcanismes lis la construction et la destruction des attributs-objets peuvent tre raliss de manire
invisible, en faisant implicitement appel au constructeur par dfaut des attributs-objets ainsi qu leur destructeur.
Ex. : La classe Personne a un attribut-objet de la classe Vehicule, qui propose un constructeur par dfaut.
Vehicule
+ Vehicule()

Personne
- age : int
- monVehicule : Vehicule
- nom : char*
+ Personne(int = 0, char* = "johndoe")
+ ~Personne()

Figure 3.17 : exemple dune classe possdant un attribut de type objet


class Vehicule
{
public:
Vehicule();
};
...

// constructeur par dfaut

class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
private:
int age;
Vehicule monVehicule;
};
...
Personne::Personne(int a, char* n)
{

//
//
//
//

l'attribut monVehicule est initialis


via un appel implicite Vehicule()
ralis avant les autres initialisations
dfinies dans Personne()

this->age = a;
this->nom = new char[strlen(n)+1];
strcpy(this->nom, n);
}
Personne::~Personne()
{
delete[] this->nom;
}

1
2

// l'attribut monVehicule est dtruit via un appel


// implicite ~Vehicule() ralis aprs les autres
// destructions dfinies dans ~Personne()

En modlisation UML, on parle dassociation (cf. D.2).


Aussi appels objets membres.
30 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Dans le cas de la construction, lappel implicite au constructeur nest en revanche plus possible lorsque la classe de
lattribut-objet ne propose pas de constructeur par dfaut ; en effet, lattribut-objet manque alors dinformations pour
initialiser correctement lensemble de ses propres attributs.
Pour pallier ce problme, il suffit de dfinir une liste dinitialisation associe au constructeur, en spcifiant, pour
chaque attribut-objet pour lequel cela savre ncessaire, lappel au constructeur avec les paramtres adquats, selon la
syntaxe :
NomClasse::NomClasse(...)
: nomAttributObjet1(paramtres_constructeur_attributObjet1)
, nomAttributObjet2(paramtres_constructeur_attributObjet2)
, ...
{ /* code du constructeur */ }

Nb : La syntaxe nomAttributObjet(paramtres_constructeur_attributObjet) est rapprocher de la


syntaxe dinstanciation dun objet utilisant une surcharge du constructeur : Classe objet(paramtres);.
Ex. : La classe Personne possde un attribut-objet de type Adresse ne possdant pas de constructeur par dfaut
(nda : par souci de lisibilit, lattribut nom a t provisoirement omis de la dclaration de la classe Personne pour tous
les exemples dinstanciation dun attribut-objet).
Vehicule

Adresse
- adrs : char*

+ Vehicule()

+ Adresse(char*)
+ ExtraireRue() : char*
+ ExtraireVille() : char*

Personne
- age : int
- monAdresse : Adresse
- monVehicule : Vehicule
+ Personne(int)

Figure 3.18 : exemple de dclaration dune classe possdant un attribut-objet sans constructeur par dfaut
class Adresse
{
public:
Adresse(char*);
// pas de constructeur par dfaut
char* ExtraireRue();
char* ExtraireVille();
private:
char* adrs;
};
...
class Personne
{
public:
Personne(int = 0);
private:
int age;
Adresse monAdresse;
Vehicule monVehicule;
};
Personne::Personne(int a)
// appel implicite Vehicule()
: monAdresse("adresse inconnue") // le constructeur monAdresse() n'existant pas,
// on ralise un appel explicite
{
// Adresse(char*) pour initialiser monAdresse
this->age = a;
}

Les paramtres passs au constructeur de lattribut-objet peuvent tre des littraux, ou bien des variables issues
directement des paramtres dappels du constructeur.
Ex. : La classe Personne possde plusieurs attributs-objets (monAdresse et maProfession) appartenant des
classes ne possdant pas de constructeur par dfaut (Adresse et Profession).

31 / 104

Programmation Oriente Objet > Langage C++ > Cours


Vehicule

v1.5.4.2 27/05/2010
Adresse

Personne

- adresse : char*
+ Vehicule()

+ Adresse(char*)
+ ExtraireRue() : char*
+ ExtraireVille() : char*

age : int
maProfession : Profession
monAdresse : Adresse
monVehicule : Vehicule

+ Personne(int)
+ Personne(int, char*, char*)

Profession
- nom : char*
- entreprise : char*
+ Profession(char*, char*)

Figure 3.19 : exemple de dclaration dune classe possdant plusieurs attributs-objets sans constructeur par dfaut
class Profession
{
public:
Profession(char*, char*);
private:
char* nom;
char* entreprise;
};
...
class Personne
{
public:
Personne(int = 0);
Personne(int, char*, char*);
private:
int age;
Adresse monAdresse;
Profession maProfession;
Vehicule monVehicule;
};
...

// pas de constructeur par dfaut

// constructeur avec des paramtres pour


// initialiser monAdresse et maProfession

Personne::Personne(int a)
: monAdresse("adresse inconnue")
, maProfession("sans profession", "")
{
this->age = a;
}

// appel aux constructeurs Adresse(char*)


// et Profession(char*, char*)

Personne::Personne(int a, char* adr, char* pro)


: monAdresse(adr)
, maProfession(pro, "n.c")

//
//
//
//
//
//
//

des paramtres permettant


d'initialiser monAdresse et
maProfession sont passs
au constructeur Personne()
pour qu'ils soient utiliss
par Adresse(char*) et
Profession(char*, char*)

this->age = a;
}

Si un objet dj instanci doit tre utilis pour construire un attribut-objet, il suffit de le passer en paramtre du
constructeur, lequel fait alors usage du constructeur de recopie de la classe de lattribut-objet.
Ex. : La classe Personne permet dinitialiser certains de ses attributs-objets (monAdresse et maProfession) en
utilisant des objets dj instancis.

32 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

class Personne
{
public:
Personne(int);
Personne(int, char*, char*);
Personne(int, Adresse, Profession);
private:
int age;
Adresse monAdresse;
Profession maProfession;
Vehicule monVehicule;
};
...

// constructeur avec des paramtres


// pour initialiser monAdresse et
// maProfession en utilisant des objets

Personne::Personne(int a, Adresse objAdr, Profession objPro)


: monAdresse(objAdr)
// appel aux constructeurs de recopie Adresse(Adresse&)
, maProfession(objPro)
// et Profession(Profession&)
{
this->age = a;
}

En ralit, le mcanisme de liste dinitialisation peut tre utilis pour tout attribut dune classe : attribut-objet sans
constructeur par dfaut, attribut-objet avec constructeur par dfaut mais que lon dsire initialiser en utilisant une
surcharge du constructeur, attribut-non-objet, etc.
La liste dinitialisation doit notamment tre imprativement utilise pour les attributs de type rfrence ainsi que les
attributs constants, mme si lon dispose dun constructeur par dfaut.
Linitialisation dun attribut constant tant ralise lors de linstanciation de lobjet, et non lors de la dclaration de
la classe (.h) 1, cela ne peut donc soprer quau moment-mme de sa dclaration.
Ex. : La classe Personne possde lattribut constant monSexe reprsentant le sexe de la personne.
class Personne
{
public:
...
Personne(int, char);
private:
int age;
const char monSexe;
Adresse monAdresse;
Profession maProfession;
Vehicule monVehicule;
};
...

// attribut constant (valeur 'm'/'f')

Personne::Personne(int a, char s)
: monAdresse("adresse inconnue")
, maProfession("sans profession", "")
, monSexe(s)
// initialisation de l'attribut constant
{
this->age = a;
}

Une rfrence ne peut tre initialise quau moment-mme de sa dclaration, en utilisant une variable / un objet du
mme type dj instanci 2.
Ex. : La classe Personne possde lattribut de type rfrence dobjet monTelephone reprsentant le numro de
tlphone de la personne.

1
2

Ce qui reviendrait donner lattribut une valeur identique pour tous les futurs objets de la classe.
cf. 2.2.2.8.
33 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

class Telephone
{
public:
Telephone();
Telephone(int num);
private:
int numero;
};
...
class Personne
{
public:
...
Personne(int, Telephone);
private:
int age;
const char monSexe;
Adresse monAdresse;
Profession maProfession;
Vehicule monVehicule;
Telephone& monTelephone;
};
...

// attribut de type rfrence

Personne::Personne(int a, Telephone t)
: monAdresse("adresse inconnue")
, maProfession("sans profession", "")
, monSexe('?')
, monTelephone(t)
// initialisation de l'attribut de type rfrence Telephone&
// avec l'objet t de type Telephone pass en paramtre
{
this->age = a;
}

3.4.3

Membres statiques

Lors de la cration dune instance laide du constructeur de recopie si besoin est le nouvel objet possde son
propre exemplaire de chaque attribut dfini dans la classe ; deux attributs homonymes appartenant chacun un objet
diffrent de la mme classe possdent donc leur propre espace mmoire et sont totalement indpendants.
De la mme manire, chaque objet a la possibilit dutiliser nimporte quelle mthode dfinie dans la classe, de
manire totalement indpendante des autres objets de la classe.
linverse, on peut dfinir certains membres comme tant communs et partags par tous les objets de la classe ; ce
sont des membres statiques. En opposition aux membres non-statiques, qui sont des attributs dinstance et des
mthodes dinstance, on les appelle aussi attributs de classe et mthodes de classe.
De fait, les membres statiques, nappartenant pas une instance, mais la classe, existent et peuvent tre appels
mme si aucune instance de la classe nexiste ou nest disponible. Les consquences sont les suivantes :
V Un attribut statique possde une valeur commune pour tous les objets de la classe, qui, si elle est modifie par
un objet, sera conserve mme si cet objet est dtruit ; linitialisation est effectue en global ;
V Une mthode statique peut tre excute de manire classique partir dune instance, mais aussi localement
sans avoir instancier dobjet ; en revanche, elle ne peut accder quaux membres statiques de la classe 1, ne
peut faire usage du pointeur this 2, et ne peut tre surcharge.
Pour dfinir un membre comme tant statique, il suffit de spcifier le modificateur static lors de la dclaration du
membre dans la dclaration de la classe, suivant la syntaxe static visibilit nomMembre;.
Par la suite, la manire dutiliser le membre statique dpend du contexte :
V dans une mthode non-statique de la classe : le membre est prfix par le pointeur this (this->membre), ou
par rien ;
V dans une mthode statique de la classe : le membre est prfix par le nom de la classe associ loprateur de
rsolution de porte (NomClasse::membre), ou par rien ;
1
2

Puisque pour accder aux membres non-statiques, il faut disposer dune instance de la classe.
Puisque this est une rfrence lobjet qui a invoqu la mthode, objet qui nexiste pas dans le cas dune mthode statique.
34 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

V autre (extrieur de la classe) : si le membre est utilis de manire classique en tant associ une instance
de la classe, il est prfix par le nom de cette instance (instance.membre / instance->membre) ; si on ne

dispose pas dinstance ou si cela na pas de sens, le membre est prfix par le nom de la classe associ
loprateur de rsolution de porte (NomClasse::membre).

Dans la reprsentation de la classe (reprsentation UML), un membre statique est soulign.


Ex. : Des membres statiques pour la classe Personne.
Personne
- age : int
- nom : char*
- nbPersonnes : int
+
+
+
+

Personne(int, char*)
~Personne()
AfficherInfos() : void
GetNbPersonnes : int

Figure 3.20 : exemple de dclaration dune classe avec des membres statiques
class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
void AfficherInfos();
static int GetNbPersonnes();
// mthode statique
private:
int age;
char* nom;
static int nbPersonnes;
// attribut statique
};
...
int Personne::nbPersonnes = 0;

// initialisation de l'attribut statique

Personne::Personne(int a, char* n)
{
this->age = a;
this->nom = new char[strlen(n)+1];
strcpy(this->nom, n);
this->nbPersonnes++;
// accs l'attribut statique commun
}
int Personne::GetNbPersonnes()
{
return Personne::nbPersonnes;
// contexte statique : prfixe 'this->'
}
// impossible
int main(void)
{
Personne eleve3(20);
cout << Personne::GetNbPersonnes() << endl;
Personne eleve4 = Personne(19);
cout << Personne::GetNbPersonnes() << endl;

// affichage: "1"
// affichage: "2"

return 0;
}

35 / 104

Programmation Oriente Objet > Langage C++ > Cours

3.4.4

v1.5.4.2 27/05/2010

Objets anonymes

La notion dobjet anonyme dsigne une instance construite mais non dclare, utilise une seule fois et localement.
On construit un objet anonyme dune classe de la mme manire quon instancie un objet laide dun constructeur 1
en statique ou en dynamique selon les syntaxes respectives NomClasse(...) ou new NomClasse(...).
Ex. : Utilisation dun objet anonyme pour retourner une nouvelle instance.
class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
void AfficherInfos();
static int GetNbPersonnes();
static Personne* AjouterPersonne();
private:
int age;
char* nom;
static int nbPersonnes;
};
...
Personne* Personne::AjouterPersonne()
{
return new Personne();
// on retourne un objet anonyme
}
int main(void)
{
Personne eleve3(20);
cout << Personne::GetNbPersonnes() << endl;
Personne* eleve14;
eleve14 = Personne::AjouterPersonne();
cout << eleve14->GetNbPersonnes() << endl;

// affichage: "1"
// ajout d'une personne
// affichage: "2"

// appel d'une mthode sur un objet anonyme


//(l'appel Personne() ajoute une personne)
cout << Personne().GetNbPersonnes() << endl;
// affichage: "3"
// nda : mieux vaudrait ici utiliser une mthode statique, afin d'viter
// l'ajout d'une personne
return 0;
}

3.4.5

Objets constants et mthodes constantes

On peut dclarer un objet constant, cest--dire que ses attributs-membres ne peuvent tre modifis pendant sa
dure de vie. On use pour cela de la mme syntaxe que les variables constantes, avec le modificateur const.
Ex. : const Personne eleve15 = Personne(12, "jan"); // instanciation d'un objet constant
Pour garantir la constance dun objet dclar constant, il faut sassurer que les mthodes qui lui sont appliques ne le
modifient pas. Pour raliser cela, les mthodes en question doivent tre des mthodes constantes, cest--dire des
mthodes qui mentionnent explicitement quelles neffectuent aucune modification lobjet sur lequel elles sont
appliques.

En effet, un constructeur (mme si aucun type de retour nest explicitement dfini) retourne bien quelque chose ; il sagit dun objet ou dune
rfrence un objet de la classe laquelle il appartient. Ce qui explique les syntaxes NomClasse nomObjet = NomClasse() (statique) et
NomClasse* nomObjet = new NomClasse() (dynamique) qui se prsentent comme une affectation (mme si une construction reste
fondamentalement diffrente dune affectation).
36 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

En effet, dans une mthode non-constante, le pointeur this est implicitement dclar NomClasse* const this 1.
Appeler une mthode non-constante sur un objet constant est impossible car cela reviendrait permettre de contourner
la dclaration constante 2. linverse, dans une mthode constante, le pointeur this est implicitement dclar
3
const NomClasse* const this , et peut donc tre initialis avec ladresse de lobjet constant.
Pour dfinir quune mthode naccde jamais quen lecture lobjet sur lequel elle est applique, et quelle ne lui
apporte donc aucune modification (que ce soit directement ou via lappel une autre mthode non-constante), on le
prcise dans le prototype de la mthode laide du modificateur const, positionn la fin, aprs la dclaration des
paramtres 4.
Ex. : La mthode AfficherInfos() neffectue aucune modification de lobjet accs en lecture uniquement. Elle
peut donc tre qualifie de const.
class Personne
{
public:
Personne(int = 0, char* = "johndoe");
~Personne();
void AfficherInfos() const; // mthode constante
private:
int age;
char* nom;
};
...
void Personne::AfficherInfos() const
{
...
}

Sil est impossible dappeler une mthode non-constante sur un objet constant, linverse est en revanche
parfaitement possible, et toute mthode constante peut tre applique un objet non-constant 5.
Lusage veut donc de qualifier de const toute mthode qui neffectue aucune modification de lobjet 6, il y a tout
y gagner 7.
Le modificateur const ajout une mthode fait partie de sa signature. Cela induit que :
V const doit tre prcis dans la dclaration de la mthode (.h), et dans son implmentation (.cpp) ;
V Une mthode constante peut tre surcharge par une mthode non-constante : on peut ainsi prciser le
comportement de la mthode selon quelle soit appele pour un objet constant ou non-constant.

3.4.6

Classes, mthodes et fonctions amies

Dans certains cas, il est ncessaire daugmenter la capacit dinteraction dune classe avec son environnement, en
permettant notamment des lments extrieurs la classe daccder aux membres non-publics.
Pour les attributs, le recours aux accesseurs est une solution, mais si on peut contrler ce qui est fait, on ne peut en
revanche contrler qui le fait, et toute classe ou fonction extrieure peut y accder ; dans le cas des mthodes, aucun
mcanisme vu jusqu prsent ne le permet 8.
Une classe peut permettre une autre classe, une fonction ou une mthode dune autre classe de devenir amie.
L amie a ainsi toute libert daccs sur les membres protgs par lencapsulation, comme si elle appartenait la
classe.
La dfinition dune amie se ralise dans la dfinition de la classe, avant la dclaration des membres en utilisant le
modificateur friend en dclarant lentit amie suivant la syntaxe friend <dclaration amie>.

1
2

3
4
5

6
7
8

Ladresse de this ne peut tre modifie (cf. 3.3.5).


Le pointeur this (non-constant) pointerait sur un objet constant : il serait possible de modifier lobjet en passant par this. Le compilateur
nautorise pas cela.
Ladresse et la valeur de this ne peuvent tre modifies.
Car positionn au dbut du prototype, le modificateur const se rapporterait au type de valeur renvoye par la mthode.
On peut contraindre temporairement un objet non-constant tre constant, tout comme on peut faire pointer un pointeur constant sur un objet
non-constant.
Ce qui exclut doffice tous les constructeurs et le destructeur.
Mthode applicable indiffremment pour objets constants et non-constants, plus de contrle lors de la compilation, meilleure lisibilit, etc.
Gnralement, si une mthode doit pouvoir tre appele de lextrieur de la classe, on lui affecte la visibilit public.
37 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : Des amies pour la classe Personne (nda : lattribut nom a t provisoirement omis de la dclaration de la
classe Personne pour cet exemple de classes, mthodes et fonctions amies).
class Personne;

// dclaration ncessaire pour que Groupe::personnes et


// et Groupe::AddPersonne(Personne) soient reconnus

class Groupe
{
public:
Groupe(int);
~Groupe();
void AfficherInfos();
void AddPersonne(Personne); /* accs libre tous les membres de Personne */
private:
int maxPersonnes;
// nombre maximal de personnes
int numPersonnes;
// nombre actuel de personnes
Personne* personnes;
};
class Personne
{
friend class Categorie;
// dclaration d'une classe amie
friend void Groupe::AfficherInfos();
// dclaration d'une mthode amie
public:
Personne(int = 0);
void AfficherInfos();
private:
int age;
};
class Categorie
{
/* accs libre tous les membres de Personne */
};
Groupe::Groupe(int max)
{
this->numPersonnes = 0;
this->maxPersonnes = max;
this->personnes = new Personne[this->maxPersonnes];
}
Groupe::~Groupe()
{
delete[] this->personnes;
}
void Groupe::AfficherInfos()
{
for ( int i=0 ; i < this->numPersonnes ; i++ ) {
cout << i << ": " << personnes[i].age << endl;
}
}
void Groupe::AddPersonne(Personne p)
{
this->personnes[this->numPersonnes++] = p;
}
...

38 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

int main(void)
{
Groupe g(10);
g.AddPersonne(Personne(20));
g.AddPersonne(Personne(19));
g.AfficherInfos();
return 0;
}

Il est noter que l amiti nest ni bijective 1, ni transitive 2 et ne shrite pas 3.


Nb : Lutilisation d amies peut traduire un dfaut de conceptualisation objet. On y a facilement recours pour
rsoudre des problmes daccs ponctuels. Nanmoins, avant de dclarer des amies , il convient tout dabord de
remettre en cause la dfinition de ses diffrentes classes.
Les amies sont en effet un moyen de contourner lencapsulation dune classe, et en ce sens ne respectent pas les
principes de la programmation objet.

1
2
3

Non-bijectivit : si B est amie de A (class A {friend class B; };), A nest pas amie de B.
Non-transitivit : si B est amie de A, que C est amie de B, C nest pas amie de A.
Non-hritage : si B est amie de A, que D hrite de A, B nest pas amie de D. Plus exactement, lamiti persiste tout de mme pour les
membres hrits : D peut donc avoir accs aux membres de B qui sont hrits de A, mais uniquement ceux-l.
39 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

4 SURCHARGE DOPRATEURS
4.1 INTRODUCTION
Pour les variables numriques, lusage des oprateurs permet de manipuler de manire induite et intuitive ces
variables entre elles, et offre la possibilit de raliser des oprations en utilisant une syntaxe naturelle.
Ex. : double x, y, z;
z = x + y;

// ajouter y x et affecter le tout dans z

En revanche, avec des objets, pour manipuler les instances dune mme classe entre eux on ne dispose que des
ventuelles mthodes que fournit la classe.
Ex. : On dispose dune classe Chaine permettant de grer des chanes de caractres.
Chaine chn1, chn2, chn3;
chn3.Copier(chn1.Concatener(chn2));

// syntaxe chn3=chn1+chn2 ne fonctionne pas

Pour augmenter la lisibilit, on dispose dun mcanisme permettant de donner un sens particulier aux oprateurs
lorsquils sont utiliss avec des objets.

4.2 PRINCIPES ET DFINITIONS


La surcharge doprateur consiste dfinir, pour un oprateur donn associ une classe, lensemble des actions
devant tre ralises lorsque cet oprateur est utilis avec une instance de cette classe.
Cette surcharge sopre en dfinissant une mthode, ou ventuellement une fonction externe la classe, sachant qu
chaque oprateur correspond une mthode implicite de nom gnrique operator<oprateur>(), et de prototype
gnrique type_retour operator<oprateur>(paramtres), sachant que les paramtres (entre et sortie)
peuvent tre du type de la classe laquelle est associe loprateur, ou bien dautres types dobjets ou de variables 1.
Les paramtres dentre peuvent tre passs par valeur ou par rfrence, sachant quil est prfrable de les passer par
rfrence dans un souci doptimisation mmoire.
Le paramtre retourn est gnralement pass par valeur lorsque la mthode cre un nouvel objet afin dassurer une
copie totale de ce qui est renvoy 2. Dans le cas des surcharges doprateurs ralisant une affectation (=, +=, =, etc.,
ainsi que ++ en princrmention), un objet existant est modifi, cest alors une rfrence qui est renvoye 3.
Mme surcharg, un oprateur conserve sa priorit, son associativit, et sa pluralit (unaire / binaire / ternaire), mais
en revanche, il perd sa commutativit. Ainsi, lorsque lon crit z = a + b + c, cela correspond
z.operator=((a.operator+(b)).operator+(c)).
Tous les oprateurs (affectation, arithmtiques, binaires, valuation dexpression, etc.) peuvent tre surchargs,
hormis :: . ?: .* sizeof. Les oprateurs =, + et << sont notamment souvent surchargs.
Hormis la surcharge de loprateur =, toutes les surcharges doprateurs, sont transmises par hritage, comme des
mthodes classiques.

1
2
3

La pertinence de lexistence et de la signification de telles surcharges dpend de la classe elle-mme, de loprateur surcharg et du contexte.
Et pas de ladresse dun objet dclar dans la mthode, qui est dtruit la fin de celle-ci ; ladresse pointerait alors sur un objet nexistant plus.
Ce qui permet aussi de chaner les oprateurs en faisant de la valeur retourne une LValue (cf. 2.2.3.3).
40 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

4.3 IMPLMENTATION
4.3.1

Surcharge doprateur par une mthode

Pour une surcharge doprateur via une mthode, le premier (ou le seul) oprande est lobjet sur lequel est appliqu
la mthode. Le prototype gnrique est donc :
V pour un oprateur unaire : X operator<oprateur>() ;
V pour un oprateur binaire : X operator<oprateur>(Y).
Ex. : La surcharge de loprateur + (concatnation de chanes) pour la classe Chaine par la mthode operator+().
Il sagit donc dun oprateur binaire, appliqu un objet Chaine, prenant en paramtre une chane et retournant une
chane. Le prototype est donc Chaine operator+(const Chaine&).
Chaine
- str : char*
+
+
+
+

Chaine(char*)
~Chaine()
GetChaine() : char*
operator+(const Chaine&) : Chaine

Figure 4.1 : exemple dune classe avec surcharge de loprateur +


class Chaine
{
public:
Chaine(char*);
~Chaine() { delete[] str; }
char* GetChaine() { return this->str; }
Chaine operator+(const Chaine&);
// surcharge de l'oprateur +
private:
char* str;
};
Chaine::Chaine(char* t)
{
this->str = new char[strlen(t)+1];
strcpy(this->str, t);
}

// allocation mmoire (avec prise en


// compte du '\0' final)

Chaine Chaine::operator+(const Chaine& chn)


{
char* nvchn;
nvchn = new char[strlen(this->str) + strlen(chn.str) + 1]; // allocation mmoire
strcpy(nvchn, this->str);
// copie de la premire chane
strcat(nvchn, chn.str);
// concatnation avec la seconde chane
return Chaine(nvchn);

// objet anonyme initialis avec la nouvelle chane

}
int main(void)
{
Chaine str1("bonjour!");
Chaine str2("ca va!");
Chaine str3 = str1 + str2;
// identique 'Chaine str3 = str1.operator+(str2)'
cout << str3.GetChaine() << endl;
// affichage: "bonjour!ca va!"
Chaine str4("");
str4 = str2 + str1;
// identique 'str4.operator=(str2.operator+(str1))'
cout << str4.GetChaine() << endl;
// affichage: "ca va!bonjour!"
return 0;
}

41 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Dans lexemple ci-dessus, il convient de distinguer les 2 syntaxes diffrentes dinitialisation dun objet :
1
c Chaine str3 = str1 + str2; : utilisation du constructeur ;
2
c Chaine str4(""); str4 = str2 + str1; : utilisation de loprateur daffectation = .
Pourtant cet oprateur daffectation = a pu tre utilis avec des objets dune classe, alors quaucune surcharge na t
dfinie pour cette classe.
Cest le compilateur qui a automatiquement gnr une surcharge basique de cet oprateur car aucune navait t
explicitement dfinie, ralisant ainsi le mme genre doprations que le constructeur de recopie cr par dfaut par le
compilateur. On peut donc lui reprocher les mmes dfauts, savoir que lors de la recopie dun attribut allou
dynamiquement, cest ladresse qui est recopie et pas le contenu point.
Les raisons justifiant dcrire le constructeur de recopie justifient donc aussi dcrire la surcharge de loprateur = ;
en toute logique, lcriture de lun implique donc lcriture de lautre.
Ex. : La surcharge de loprateur = pour la classe Chaine par la mthode Chaine& operator=(Chaine), ainsi
que la surcharge du constructeur de recopie.
Chaine
- str : char*
+
+
+
+
+
+

Chaine(char*)
Chaine(const Chaine&)
~Chaine()
GetChaine() : char*
operator+(const Chaine&) : Chaine
operator=(const Chaine&) : Chaine&

Figure 4.2 : exemple dune classe avec surcharge des oprateurs + et =


class Chaine
{
public:
Chaine(char*);
Chaine(const Chaine&);
// constructeur de recopie
~Chaine() { delete[] str; }
char* GetChaine() { return this->str; }
Chaine operator+(const Chaine&);
Chaine& operator=(const Chaine&);
// surcharge de l'oprateur =
private:
char* str;
};
...
Chaine::Chaine(const Chaine& chn)
{
this->str = new char[strlen(chn.str) + 1];
strcpy(this->str, chn.str);
}

// allocation mmoire

Chaine& Chaine::operator=(const Chaine& chn)


{
delete this->str;
// destruction de l'ancien objet
this->str = new char[strlen(chn.str) + 1];
// nouvelle allocation mmoire
strcpy(this->str, chn.str);
return *this;
}

1
2

Plus prcisment, dans lordre, appel de : operator+(), constructeur Chaine(char*).


Plus prcisment, dans lordre, appel de : constructeur Chaine(char*), operator+(), constructeur Chaine(char*), operator=().
42 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

int main(void)
{
Chaine str1("bonjour!");
Chaine str2("ca va!");
Chaine str3 = str1 + str2;
// appel au constructeur Chaine(char*)
cout << str3.GetChaine() << endl;
// affichage: "bonjour! ca va!"
Chaine str4("");
// appel au constructeur Chaine(char*)
str4 = str2 + str1;
// appel l'oprateur =
cout << str4.GetChaine() << endl;
// affichage: "ca va! bonjour!"
return 0;
}

Comme toute mthode, les surcharges doprateurs peuvent tre surcharges.


Ex. : Une surcharge additionnelle de loprateur + pour la classe Chaine par la mthode Chaine
operator+(char).
Chaine
- str : char*
+
+
+
+
+
+
+

Chaine(char*)
Chaine(const Chaine&)
~Chaine()
GetChaine() : char*
operator+(const Chaine&) : Chaine
operator+(char) : Chaine
operator=(const Chaine&) : Chaine&

Figure 4.3 : exemple dune classe avec plusieurs surcharges pour un oprateur
class Chaine
{
public:
Chaine(char*);
Chaine(const Chaine&);
~Chaine() { delete[] str; }
char* GetChaine() { return this->str; }
Chaine operator+(const Chaine&);
// surcharge de l'oprateur + (1)
Chaine operator+(char);
// surcharge de l'oprateur + (2)
Chaine& operator=(const Chaine&);
private:
char* str;
};
...
Chaine Chaine::operator+(char c)
{
char* nvchn = new char[strlen(this->str) + 2];
strcpy(nvchn, this->str);
nvchn[strlen(this->str)] = c;
nvchn[strlen(this->str)+1] = '\0';
return Chaine(nvchn);
}
int main(void)
{
Chaine str1("bonjour!");
Chaine str5 = str1 + '?';
cout << str5.GetChaine() << endl;

// affichage: "bonjour!?"

return 0;
}

43 / 104

Programmation Oriente Objet > Langage C++ > Cours

4.3.2

v1.5.4.2 27/05/2010

Surcharge doprateur par une fonction

Certains oprateurs (comme << et >>) ne peuvent pas tre surchargs par les mthodes dune classe car ils font
intervenir des types primitifs ou bien des classes auxquelles le programmeur na pas accs (Ex. : classes de la STL). Il
faut alors utiliser une fonction externe la classe.
Le prototype gnrique de la surcharge dun oprateur par une fonction est :
V pour un oprateur unaire : X operator<oprateur>(Y) ;
V pour un oprateur binaire : X operator<oprateur>(Y, Z).
Nb : Une pratique courante veut que les fonctions de surcharges doprateurs soient dclares amies de la classe
afin quelles puissent accder aux attributs de la classe. On choisira plutt de dclarer des accesseurs en lecture pour
tous les attributs devant tre accessibles et utiliser ceux-ci dans les fonctions de surcharges doprateurs.
<<
pour
Ex. : La
surcharge
de
loprateur
1
ostream& operator<<(ostream&, const Chaine&) .

la

classe

Chaine

par

la

fonction

class Chaine
{
public:
Chaine(char*);
Chaine(const Chaine&);
~Chaine() { delete[] str; }
char* GetChaine() const { return this->str; }
// mthode constante
Chaine operator+(const Chaine&);
// surcharge de l'oprateur + (1)
Chaine operator+(char);
// surcharge de l'oprateur + (2)
Chaine& operator=(const Chaine&);
private:
char* str;
};
...
ostream& operator<<(ostream& os, const Chaine& chn)
{
os << chn.GetChaine();
return os;
}
int main(void)
{
Chaine str1("bonjour!");
Chaine str2("ca va!");
cout << str1 << str2 << endl;
return 0;

// affichage: "bonjour!ca va!"

Gnralement, si lune des mthodes parmi le destructeur, le constructeur de recopie ou la surcharge de loprateur
daffectation est rcrite, cest que la version basique produite par le compilateur ne convient pas.
On prendra alors soin de rcrire imprativement les 2 autres : cest ce quon appelle la rgle des trois.
Cette rgle des trois se retrouve dans la forme canonique de Coplien. Il sagit dun ensemble minimum de mthodes
permettant de manipuler sans problme des instances de toute classe ayant comme caractristique de possder au
moins 1 attribut allou dynamiquement, et dfinie ainsi :
Class NomClasse
{
public:
NomClasse();
// constructeur par dfaut
NomClasse(const NomClasse&);
// constructeur de recopie
~NomClasse();
// destructeur (ventuellement virtuel)
NomClasse& operator=(const NomClasse&);
// surcharge oprateur =
};
1

Cette fonction surcharge la fonction dj existante operator<<() afin que loprateur << puisse traiter les objets du type Chaine.
44 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

5 LHRITAGE DE CLASSES
Lhritage de classe, concept fondamental de la POO, dfinit quune nouvelle classe peut tre cre partir dune
classe dj existante. Cela permet ainsi de prciser, ou mettre jour une classe.
On distingue :
V lhritage simple : une classe est cre partir dune seule classe ;
V lhritage multiple : une classe est cre partir de plusieurs classes.

5.1 LHRITAGE SIMPLE


5.1.1

Principes

Lhritage simple dsigne le cas o une nouvelle classe est cre partir dune et dune seule classe dj existante.
La nouvelle classe possde alors automatiquement une copie des membres de la classe dj existante, lesquels peuvent
tre complts par de nouveaux.
Dans le cadre dun hritage o ClasseA existe et permet de crer ClasseB, ClasseA classe dj existante est
appele la super-classe, et ClasseB nouvelle classe est appele la sous-classe. On parle aussi de drivation de la
super-classe en sous-classe ; on drive la classe de base, ClasseA, pour obtenir alors une classe drive, ClasseB.
Dans la reprsentation UML, lhritage est symbolis par une flche tte triangulaire vide qui relie les 2 classes
dans le sens sous-classe d super-classe.
SuperClasse

SousClasse

Figure 5.1 : reprsentation UML dune relation dhritage simple

Ex. : Soit une classe qui reprsente un vhicule, et une autre qui reprsente une voiture. Une voiture est une sorte
de vhicule ; dans la relation Vehicule/Voiture, Vehicule est donc la super-classe, et Voiture la sous-classe.
Vehicule

Voiture

Figure 5.2 : exemple dun hritage simple entre deux classes

Dans lhritage simple, une sous-classe ne peut hriter que dune seule classe. En revanche, une classe peut servir de
classe de base pour plusieurs classes drives.
Si besoin est, les membres peuvent tre redfinis dans la sous-classe ; ainsi, les mthodes hrites peuvent tre
redfinies par surcharge dans la classe drive, afin dtre plus adaptes ce que reprsente cette classe.
En ralit, laccs dans la sous-classe aux membres hrits dpend de leur visibilit 1 :
V membre public de la classe de base : devient un membre public de la classe drive ;
V membre priv de la classe de base : est inaccessible par la classe drive.
Lencapsulation est donc pleinement respecte par lhritage.
On observe alors un dilemme : comment avoir effectivement une copie des attributs dans la sous-classe sans risque
de viol potentiel de lencapsulation 2 ?
La solution passe par lutilisation dun troisime caractre de visibilit, qui est le caractre protg (protected) :
V membre protg de la classe de base : devient un membre protg de la classe drive.
1
2

Il sagit des capacits daccs et non de la prsence des membres : tous les membres hrits sont bien prsents, mais certains sont inaccessibles.
Car si un attribut de la classe de base est dclar public, il est alors disponible dans la classe drive, mais il lest de fait aussi pour nimporte
quelle autre classe.
45 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Un membre protg est inaccessible de lextrieur de la classe (respect de lencapsulation), mais est disponible pour
les classes drives (atout de lhritage).
Dans la reprsentation UML de la classe, un membre protg est prcis dun # (dise) devant son nom.
Ex. : Soit une classe reprsentant une voiture et une classe reprsentant un vlo, drives dune classe Vehicule,
ayant accs certains membres hrits de la classe de base tout en respectant lencapsulation.
Voiture
Vehicule
#
#
#
-

couleur : int
marque : char*
modele : char*
type : char*

+
+
+
+
+

Vehicule()
~Vehicule()
Accelerer() : void
Arreter() : void
Demarrer() : void

- puissance : int
+ Voiture()
+ ~Voiture()
+ FairePlein(int) : void

Velo
- nbVitesses : int
+ Velo()
+ ~Velo()
+ ChangerPneu() : void

Figure 5.2 : exemple dutilisation de lhritage

Les attributs couleur, marque et modele de la classe Vehicule seront donc disponibles dans les classes
Voiture et Velo. En revanche, lattribut type (chane reprsentant le type de vhicule : camion ,
voiture , bateau , etc.) restera indisponible aux classes drives.

5.1.2

Implmentation

Pour spcifier quune classe drive dune autre classe, il faut indiquer, la dclaration de la classe, le nom de la
classe de base, suivant la syntaxe class SousClasse : SuperClasse { ... };.
Ex. : La classe Employe drive de la classe Personne.
Personne
# age : int
# initiale : char
+ Personne()
+ ~Personne()
+ AfficherInfos() : void

Employe
# profession : char*
+ Employe()
+ ~Employe()
+ AfficherInfosSups() : void

Figure 5.3 : exemple dimplmentation dun hritage simple


class Personne
{
public:
Personne();
~Personne();
void AfficherInfos();
protected:
int age;
char initiale;
};

5.1.3

class Employe : Personne


{
public:
Employe();
~Employe();
void AfficherInfosSups();
protected:
char* profession;
};

Relations entre classe de base et classe drive

Laction de drivation implique plusieurs relations entre la classe de base et la classe drive :
1
V recopie des membres de la classe de base , conformment leur visibilit ;
V appel du constructeur de la classe de base avant lappel du constructeur de la classe drive, afin dinitialiser
les attributs hrits ;
V appel du destructeur de la classe de base aprs lappel du destructeur de la classe drive, afin de raliser les
oprations ncessaires la destruction propre dfinies par la classe de base.
1

Sont exclus de lhritage : tous les constructeurs (dfaut, non par dfaut, de recopie) ainsi que la ou les surcharges de loprateur
daffectation = (operator=()).
46 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : La classe Employe drive de la classe Personne.


Personne::Personne()
{
cout << "Personne()" << endl;
this->age = 0;
this->initiale = '?';
}
Personne::~Personne()
{
cout << "~Personne()" << endl;
}
void Personne::AfficherInfos()
{
cout << "age " << this->age << endl;
cout << "initiale " << this->initiale << endl;
}
Employe::Employe()
{
cout << "Employe()" << endl;
this->profession = new char[10];
this->profession = "n.c";
}
Employe::~Employe()
{
delete this->profession;
cout << "~Employe()" << endl;
}
void Employe::AfficherInfosSups()
{
cout << "age " << this->age << endl;
cout << "initiale " << this->initiale << endl;
cout << "profession " << this->profession << endl;
}
int main(void)
{
Employe* emp1;
// dclaration d'un objet Employe (pas de construction)
emp1 = new Employe;
// affichage: "Personne()" | "Employe()"
emp1->AfficherInfosSups();
// affichage: "0" | "?" | "n.c"
delete emp1;
// affichage: "~Employe()" | "~Personne()"
return 0;
}

Cest donc le constructeur par dfaut de la super-classe qui est excut.


Dans le cas o la classe de base ne possde pas de constructeur par dfaut, ou quil est prfrable de faire appel
une version surcharge du constructeur (possdant 1 ou plusieurs paramtres), il faut alors spcifier explicitement
lappel au constructeur de la classe de base, en utilisant la syntaxe 1 :
SousClasse::SousClasse(...)
: SuperClasse(paramtres)
{ /* code du constructeur */ }

Les paramtres peuvent tre de type fini ou bien tre des variables issues des paramtres dappel du constructeur de
la sous-classe :
SousClasse::SousClasse(type_paramtre1 parametre1, type_paramtre2 parametre2, ...)
: SuperClasse(parametre2, ...)
{ /* code du constructeur */ }
1

Cette syntaxe est similaire celle utilise lors de la dclation dune liste dinitialisation (cf. 3.4.2) ; si les 2 concepts demeurent totalement
diffrents, leur usage peut tre mlang sans problme, car servant en ralit la mme cause : linitialisation des attributs de lobjet.
47 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : class Personne


{
public:
Personne(int = 0, char = '?');
void AfficherInfos();
protected:
int age;
char initiale;
};
...
Personne::Personne(int a, char i)
{
this->age = a;
this->initiale = i;
}
class Employe : Personne
{
public:
Employe();
Employe(int, char);
~Employe();
void AfficherInfosSups();
protected:
char* profession;
};
...
Employe::Employe()
// appel du constructeur Personne(int, char)
: Personne(1, '-')
// avec des paramtres de valeur finie
{
this->profession = new char[10];
this->profession = "n.c";
}
Employe::Employe(int a, char i)
// appel du constructeur Personne(int, char)
: Personne(a, i)
// avec des paramtres issus des paramtres
{
// d'appel du constructeur Employe(int, char)
this->profession = new char[10];
this->profession = "n.c";
}
int main(void)
{
Employe emp2;
emp2.AfficherInfosSups(); // affichage: "1" | "-" | "n.c"
Employe emp3(20, 'a');
emp3.AfficherInfosSups(); // affichage: "20" | "a" | "n.c"
return 0;
}

L encore, lusage des valeurs par dfaut pour les paramtres des constructeurs permet de faire correspondre
plusieurs surcharges 1 seul constructeur.
Ex. : class Employe : Personne
{

public:
Employe(int = 1, char = '-'); // Employe(), Employe(int), Employe(int, char)
~Employe();
void AfficherInfosSups();
protected:
char* profession;
};
...

48 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Employe::Employe(int a, char i)
: Personne(a, i)
{
this->profession = new char[10];
this->profession = "n.c";
}

Lorsque lon redfinit (/re-dclare) un membre 1 dans la classe drive, le membre originel nest pas remplac mais
cach par le membre redfini 2. En pratique, on redfinit rarement un attribut ; en revanche, il est gnralement
pertinent de redfinir une mthode, afin de la spcialiser pour la classe drive.
Ex. : class Employe : Personne
{

public:
Employe(int = 1, char = '-');
~Employe();
void AfficherInfos();
// redfinition de la mthode
protected:
char* profession;
};
...
void Employe::AfficherInfos()
{
cout << "age " << this->age << endl;
cout << "initiale " << this->initiale << endl;
cout << "profession " << this->profession << endl;
}
int main(void)
{
Employe emp3(20, 'a');
emp3.AfficherInfos();
// affichage: "20" | "a" | "n.c"
return 0;
}

Nanmoins, les membres hrits, cachs par les membres redfinis, restent accessibles en utilisant loprateur de
rsolution de porte, suivant la syntaxe SuperClasse::membre.
Ex. : void Employe::AfficherInfos()
{

this->Personne::AfficherInfos();
// appel de AfficherInfos() de Personne
cout << "profession: " << this->profession << endl;
}

5.1.4

Modes de drivation

Le mode de drivation permet de spcifier les modifications apportes dans la classe drive la visibilit des
membres hrits de la classe de base.
On distingue 3 modes de drivation (/mode dhritage) :
V public: les membres publics et protgs conservent la mme visibilit ;
V protg : les membres publics deviennent protgs, alors que les membres protgs conservent leur visibilit ;
V priv : les membres publics et protgs deviennent des membres privs.
Dans tous les cas, les membres privs restent inaccessibles.
Le mode de drivation se spcifie lors de la dclaration de la sous-classe, en utilisant lun des mots-clefs public /
protected / private suivant la syntaxe class SousClasse : mode_drivation SuperClasse { ... };.
Ex. : La classe Employe drive de la classe Personne suivant un hritage public.

1
2

Dans le cas de la redfinition dune mthode, on peut parler de surcharge .


Mme dans le cas dune redfinition dune mthode avec une mthode de signature diffrente.
49 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

class Employe : public Personne


{
...
};

Lhritage public est la forme la plus courante dhritage : elle ne dnature pas la visibilit des membres.
Si aucun mode de drivation nest prcis, cest lhritage priv qui est utilis 1.

hritage
public
hritage
protg
hritage
priv

visibilit dans la classe de base


public
protected
private
public
protected
private
public
protected
private

visibilit dans la classe drive


public
protected
inaccessible
protected
protected
inaccessible
private
private
inaccessible

Nanmoins, dans le cas des hritages protg et priv, il est possible de mentionner des exceptions ; certains
membres peuvent ainsi conserver leur visibilit, et ce malgr le mode de drivation. Cest ce quon appelle la
dclaration daccs.
Pour ce faire, il faut utiliser loprateur de rsolution de porte dans la dfinition de la classe drive, en forant la
redclaration du membre dans la section de visibilit adquate, suivant la syntaxe SuperClasse::membre;
(uniquement le nom, pas de modificateurs, paramtres, etc., mme pas de parenthses).
Ex. : class Personne
{

public:
Personne(int = 0, char = '?');
void AfficherInfos();
protected:
int age;
char initiale;
};
class Employe : private Personne
// hritage priv : tous les membres publics
{
// et protgs hrits obtiennent par dfaut
public:
// une visibilit prive
Employe(int = 1, char = '-');
~Employe();
Personne::AfficherInfos;
// redclaration de la mthode AfficherInfos()
protected:
// pour conserver une visibilit publique
char* profession;
Personne::age;
// redclaration de l'attribut age pour conserver
};
// une visibilit protge
// l'attribut initiale, non-redclar, reste priv

Nb : La dclaration daccs permet uniquement de conserver la visibilit originelle, mais en aucun cas de la
modifier (laugmenter ou la rduire).

5.2 LE POLYMORPHISME
Le polymorphisme 2 dsigne la capacit pour une mthode adopter un comportement diffrent selon lobjet
auquel elle est applique ou bien le nombre ou le type de paramtres avec lesquels elle est appele.

5.2.1

Hirarchie des classes

Tout lintrt de lhritage rside dans les corrlations qui existent entre diffrentes classes. Avec un ensemble de
classes lies par des relations dhritage, parfois successifs, une hirarchie de classes peut ainsi tre dfinie.
1
2

Cest donc celui qui tait utilis dans ce chapitre jusquici.


Mot dtymologie grecque signifiant peut prendre plusieurs formes .
50 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Lorsquune modification est alors apporte un membre non priv dune classe, toutes les classes drives subissent
automatiquement la modification.
Ex. : Une hirarchie de classes reprsentant lorganisation des personnes dans un contexte professionnel.
Personne

Employe

Ouvrier

Contact

Cadre

Directeur

Contractuel

CoRegulier

CoPonctuel

Figure 5.4 : exemple de hirarchie de classes

Ainsi, si on rajoute lattribut protg email la classe Personne, et que tous les hritages entre les classes sont
publics, cet attribut sera automatiquement disponible dans toutes ses sous-classes.
Lhritage de classe implique une forte cohsion entre les classes dune mme hirarchie. Ainsi, si on considre la
classe Cadre, on peut dire que Cadre est une sorte dEmploye, alors que Employe est elle-mme une sorte de
Personne ; par consquent, Cadre est aussi une sorte de Personne. En revanche, Personne nest pas
ncessairement Employe, Directeur, ou Contact.
Ces relations permettent alors de mettre en vidence des conversions possibles entre classes.

5.2.2

Conversion vers une classe de base

Une hirarchie de classes implique que lon peut considrer (/ rduire ) un objet dune classe drive comme une
sorte dobjet de la classe de base (niveau suprieur direct ou indirect) ; en revanche, il est impossible de considrer
(/ tendre ) un objet dune classe de base comme un objet de lune de ses classes drives.
Autrement dit, la conversion vers une classe de base dune instance dune classe drive est possible. Il sen suit
que diffrentes critures mlant classe de base et classe drive dune mme hirarchie de classe sont lgitimes.
Ex. : La hirarchie de classes de personnes dans un contexte professionnel permet dcrire :
Personne unePersonne1;
Ouvrier unOuvrier1;
unePersonne1 = unOuvrier1;

// instanciation statique d'un objet Personne en


// utilisant un objet Ouvrier dj cr

Personne* unePersonne2;
Cadre* unCadre2;
unCadre2 = new Cadre();
unePersonne2 = unCadre2;

// instanciation dynamique d'un objet Personne en


// utilisant un objet Cadre dj cr

Personne* unePersonne3 = new Cadre();

// idem en criture restreinte

Personne* unePersonne4;
Contractuel unContractuel4;
unePersonne4 = &unContractuel4;

// instanciation dynamique d'un objet Personne


// en utilisant l'adresse d'un objet
// Contractuel dj cr

void uneFonction5(Personne p)
{
p.AfficherInfos();
}
...
Employe unEmploye5;
uneFonction5(unEmploye5);

// uneFonction5 attend un objet Personne : usage


// implicite du constructeur par dfaut

// l'appel de la fonction, l'objet Personne


// est construit en utilisant un objet Employe

void uneFonction6(Personne* p)
{
p->AfficherInfos();
}
...
Directeur unDirecteur6;
uneFonction6(&unDirecteur6);

51 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Nb : Ces diffrentes conversions sont possibles uniquement si les hritages mis en jeu sont publics 1.
Ainsi, l o on attend une instance de la classe de base, on peut donc utiliser une instance de la classe drive, car la
classe drive contient au moins les membres de la classe de base ; linverse est en revanche impossible, certaines
informations manquent pour construire correctement lobjet de la classe drive partir des donnes dun objet de la
classe de base.
Ouvrier
Personne

Personne

Personne

?
Personne

Personne

Personne
?

Ouvrier
?

Figure 5.5 : exemple de conversion de type dans une hirarchie de classes

Plus prcisment, dans le cas dune dclaration statique, la conversion entrane effectivement une perte
dinformations ; dans le cas dune dclaration dynamique (pointeur ou rfrence), la conversion ne fait pas perdre
dinformations, mais linstance ne permet plus daccder tous les membres.

5.2.3

Gnralisation

La hirarchie dun ensemble de classes autorise donc les dclarations suivantes :


SousClasse objSousClasse;
SuperClasse objSuperClasse = objSousClasse;
SuperClasse* ptrSuperClasse = &objSousClasse;
SuperClasse& refSuperClasse = objSousClasse;

La question peut se poser de savoir de quel type est alors effectivement chacune des instances dclares. Pour la
dclaration statique (objSuperClasse), on sait que la conversion implique la perte des informations superflues. En
revanche, dans le cas de la dclaration dynamique, le doute est permis.
Cest ici quintervient la distinction, pour une instance, de typage statique ou de typage dynamique :
V type statique : type utilis la dclaration ;
2
V type dynamique : type utilis la construction de linstance .
Ainsi, ptrSuperClasse et refSuperClasse sont du type statique SuperClasse, mais sont du type dynamique
SousClasse.
Le typage dynamique conduit la notion de gnralisation 3 lorsquun ensemble dinstances diffrentes drivent
tous de la mme classe de base. Cette proprit permet de dclarer des pointeurs dune mme classe et de construire
chacun dentre eux comme une instance dune classe drive diffrente.
Cela se rvle pratique pour regrouper des traitements effectus sur divers objets de type statique identique, mais de
type dynamique diffrent.
Ex. : Usage de la gnralisation dans une hirarchie de classes.

1
2

La classe de base doit conserver des membres publics accessibles.


Sachant que linstance dun objet peut tre construite plusieurs fois donc de manire diffrente durant une seule et mme excution du
programme.
Linverse tant la spcialisation : on drive une classe en une sous-classe pour la spcialiser aux besoins.
52 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Polygone

Pentagone

# nbCotes : int
+ Pentagone()

+ GetNbCotes() : int
+ SePresenter() : void

Rectangle

Triangle

+ Rectangle()

+ Triangle()

Figure 5.6 : exemple de mise en uvre de la gnralisation


class Polygone
{
public:
int GetNbCotes() { return this->nbCotes; }
void SePresenter() { cout << "polygone" << endl; }
protected:
int nbCotes;
};
class Triangle : public Polygone
{
public:
Triangle() { this->nbCotes = 3; }
};
class Rectangle : public Polygone
{
public:
Rectangle() { this->nbCotes = 4; }
};
class Pentagone : public Polygone
{
public:
Pentagone() { this->nbCotes = 5; }
};
Polygone* figures[4];
int main(void)
{
figures[0] =
figures[1] =
figures[2] =
figures[3] =

new
new
new
new

// liste des figures (ensemble d'objets ayant


// mme type statique Polygone*)

Polygone();
Triangle();
Rectangle();
Pentagone();

//
//
//
//

instanciation d'objets diffrents : ils ont


un type dynamique diffrent du type statique
(ajout d'un triangle, d'un rectangle et d'un
pentagone la liste des figures)

for ( int i=0 ; i<4 ; i++ ) {


cout << figures[i]->GetNbCotes() << endl; // affichage: "0" | "3" | "4" | "5"
}
return 0;
}

Malgr tout, lors de la redfinition de membres, cest le type statique qui prime lorsquune instance a un type
dynamique diffrent ; le type est effectivement dtermin la compilation (type statique) et non lexcution (type
dynamique) 1. Ainsi, cest la version de la mthode correspondant au type statique qui est appele, mme si
linstance a un type dynamique diffrent.
Ex. : Les limites de la gnralisation dans une hirarchie de classes.
1

On parle de ligature statique : caractristique qui provient du souci de compatibilit avec le langage C dont est issu le langage C++.
53 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Polygone

Pentagone

# nbCotes : int
+ GetNbCotes() : int
+ SePresenter() : void

+ Pentagone()
+ SePresenter() : void

Rectangle

Triangle

+ Rectangle()
+ SePresenter() : void

+ Triangle()
+ SePresenter() : void

Figure 5.7 : exemple de rdfinition dun membre dans une relation de gnralisation
...
class Triangle : public Polygone
{
public:
Triangle() { this->nbCotes = 3; }
void SePresenter() { cout << "triangle" << endl; }
};
class Rectangle : public Polygone
{
public:
Rectangle() { this->nbCotes = 4; }
void SePresenter() { cout << "rectangle" << endl; }
};
class Pentagone : public Polygone
{
public:
Pentagone() { this->nbCotes = 5; }
void SePresenter() { cout << "pentagone" << endl; }
};
Polygone* figures[4];
int main(void)
{
figures[0] =
figures[1] =
figures[2] =
figures[3] =

new
new
new
new

Polygone();
Triangle();
Rectangle();
Pentagone();

for ( int i=0 ; i<4 ; i++ ) {


figures[i]->SePresenter();
cout << figures[i]->GetNbCotes() << endl;
}

// affichage: "polygone 0" |


// "polygone 3" | "polygone 4" |
// "polygone 5" |

return 0;
}

Cette caractristique parat bien peu pratique, et limite fortement lintrt de lhritage et de la gnralisation 1.
Mais, si on reste bloqu pour les attributs, il existe cependant une solution concernant les mthodes ; il suffit de mettre
en uvre les mthodes virtuelles.

On imagine trs bien un traitement identique appliquer un ensemble dobjets de types dynamiques diffrents.
54 / 104

Programmation Oriente Objet > Langage C++ > Cours

5.2.4

v1.5.4.2 27/05/2010

Mthodes virtuelles

Une mthode dclare comme virtuelle dans la classe de base se fonde sur le type dynamique pour tre excute.
Cest--dire que pour une instance ayant comme type dynamique une classe drive et comme type statique la classe
de base 1, cest la redfinition de la mthode qui sera appele si celle-ci a t surcharge. Lexcution sadapte ainsi
exactement ce quest lobjet au moment de lexcution du programme.
Pour dclarer une mthode virtuelle, on utilise le modificateur virtual dans la dfinition de la classe de base
suivant la syntaxe virtual type_mthode NomMethode(type_paramtre_1, type_paramtre_2, ...).
Ex. : Usage des mthodes virtuelles dans une hirarchie de classes.
Polygone

Pentagone

# nbCotes : int
+ GetNbCotes() : int
+ SePresenter() : virtual void

+ Pentagone()
+ SePresenter() : void

Rectangle

Triangle

+ Rectangle()
+ SePresenter() : void

+ Triangle()
+ SePresenter() : void

Figure 5.8 : exemple de mise en uvre dune mthode virtuelle


class Polygone
{
public:
int GetNbCotes() { return this->nbCotes; }
virtual void SePresenter() { cout << "polygone" << endl; }
protected:
int nbCotes;
};

// virtuelle

...
int main(void)
{
figures[0] =
figures[1] =
figures[2] =
figures[3] =

new
new
new
new

Polygone();
Triangle();
Rectangle();
Pentagone();

for ( int i=0 ; i<4 ; i++ ) {


figures[i]->SePresenter();
cout << figures[i]->GetNbCotes() << endl;
}

//
//
//
//

affichage: "polygone 0" |


"triangle 3" |
"rectangle 4" |
"pentagone 5"

return 0;
}

Une dclaration virtuelle nimplique pas une redfinition obligatoire de la mthode dans les classes drives, mais
est significative dune souplesse potentielle pour les futures classes drives.
Cette caractristique se propage aussi bien pour les classes drives directes que les classes drives indirectes.
Ainsi, ds quune mthode est dclare virtuelle, elle lest pour toute la partie infrieure de la hirarchie de classes.
Ex. : Propagation de la qualit virtuelle dune mthode aux sous-classes.

Ceci exclut donc les instances statiques de la classe de base car elles ne peuvent tre construites que comme objets de la classe de base, et
pas comme objets dune classe drive.
55 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Polygone

Pentagone

# nbCotes : int
+ GetNbCotes() : int
+ SePresenter() : virtual void

+ Pentagone()
+ SePresenter() : void

Rectangle

Triangle

+ Rectangle()
+ SePresenter() : void

+ Triangle()
+ SePresenter() : void

TriangleIsocele

+ SePresenter() : void

Figure 5.9 : exemple de propagation dune dclaration virtuelle


...
class Triangle : public Polygone // aucun changement la classe Triangle
{
public:
Triangle() { this->nbCotes = 3; }
void SePresenter() { cout << "triangle" << endl; } // dclaration virtuelle
};
// inutile : hrit de
// Polygone
class TriangleIsocele : public Triangle
{
public:
void SePresenter() { cout << "isocele" << endl; }
};
...
int main(void)
{
figures[0] =
figures[1] =
figures[2] =
figures[3] =

new
new
new
new

Polygone();
TriangleIsocele();
Rectangle();
Pentagone();

for ( int i=0 ; i<4 ; i++ ) {


figures[i]->SePresenter();
cout << figures[i]->GetNbCotes() << endl;
}

// affichage: "polygone 0" |


// "isocele 3" | "rectangle 4" |
// "pentagone 5" |

return 0;
}

Attention : Lors de lutilisation dune mthode virtuelle, le destructeur, sil est redfini, doit lui aussi tre dclar
virtuel dans la classe de base, afin de sassurer que ce soit le destructeur de la classe hrite qui soit excut la
destruction dun objet.

5.2.5

Mthodes virtuelles pures et classes abstraites

Lorsquune mthode virtuelle est dclare dans une classe de base, mais que son implmentation ne peut pas tre
donne ou na pas de sens alors quelle en a dans les classes drives, on peut alors dclarer la mthode comme tant
virtuelle pure.
Une mthode virtuelle pure est une mthode dfinissant un concept dans la classe de base, mais dont
limplmentation nest pas donne ; en revanche, limplmentation de la mthode devra obligatoirement tre fournie
par toute classe drive.
On dfinit une mthode virtuelle pure en rajoutant = 0 dans la dfinition de la classe suivant la syntaxe
virtual type_mthode NomMethode(type_paramtre_1, type_paramtre_2, ...) = 0.
Dans la reprsentation UML dune classe, le nom dune mthode virtuelle pure est crite en italique.
Ex. : Une classe abstraite dans une hirarchie de classes.

56 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Polygone

Pentagone

# nbCotes : int
+ GetNbCotes() : int
+ SeDessiner() : virtual void
+ SePresenter() : virtual void

+ Pentagone()
+ SeDessiner() : void
+ SePresenter() : void

Rectangle

Triangle

+ Rectangle()
+ SeDessiner() : void
+ SePresenter() : void

+ Triangle()
+ SeDessiner() : void
+ SePresenter() : void

TriangleIsocele

+ SeDessiner() : void
+ SePresenter() : void

Figure 5.10 : exemple de mise en uvre dune mthode virtuelle pure et dune classe abstraite
class Polygone
{
public:
int GetNbCotes() { return this->nbCotes; }
virtual void SeDessiner() = 0;
// pas d'implmentation pour cette mthode
virtual void SePresenter() { cout << "polygone" << endl; }
protected:
int nbCotes;
};
class Triangle : public Polygone
{
public:
Triangle() { this->nbCotes = 3; }
void SeDessiner() { cout << "dessin triangle" << endl; }
void SePresenter() { cout << "triangle" << endl; }
};
class Rectangle : public Polygone
{
public:
Rectangle() { this->nbCotes = 4; }
void SeDessiner() { cout << "dessin rectangle" << endl; }
void SePresenter() { cout << "rectangle" << endl; }
};
class Pentagone : public Polygone
{
public:
Pentagone() { this->nbCotes = 5; }
void SeDessiner() { cout << "dessin pentagone" << endl; }
void SePresenter() { cout << "pentagone" << endl; }
};

Dfinir une mthode virtuelle pure permet de sassurer que celle-ci sera assurment surcharge dans les classes
drives, ce qui savre ncessaire lorsque la mthode reprsente un concept gnrique inutilisable trs haut niveau.
Lorsquune mthode est dclare virtuelle pure, son implmentation na donc pas de sens 1 ; en consquence, toute
classe ayant au moins 1 mthode virtuelle pure ne peut tre construite 2 et on dit alors que la classe est abstraite. La
classe est destine demeurer une classe concept , soit donc une classe servant de modle pour dautres classes.
Dans la reprsentation UML, le nom dune classe abstraite est crite en italique.
Si une mthode virtuelle pure hrite ne peut tre implmente compltement dans la classe drive, cela signifie
quelle doit tre aussi dclare virtuelle pure, et de fait, la classe qui la contient est abstraite.
Nb : Par extension, on peut parler de mthode abstraite dans le cas dune mthode virtuelle pure.

1
2

Elle peut cependant tre conserve, mais elle nest pas prise en compte par le compilateur.
Car il existe au moins une mthode nayant pas dimplmentation.
57 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

5.3 LHRITAGE MULTIPLE


5.3.1

Principes

Lhritage multiple dsigne le cas o une nouvelle classe est cre partir de plusieurs classes dj existantes. La
nouvelle classe hrite donc de tous les membres de chacune des super-classes, au regard du mode dhritage utilis
pour chacune, et de la visibilit de chacun des membres.
SuperClasse1

SousClasse

SuperClasse2

Figure 5.11 : reprsentation UML dun hritage multiple

5.3.2

Implmentation

Pour indiquer quune classe drive de plusieurs classes, on procde comme pour lhritage simple suivant la syntaxe
class SousClasse : mode_driv1 SuperClasse1, mode_driv2 SuperClasse2, ... { ... };.

Ex. : La classe DelegueSyndical drive des classes Employe et Syndicaliste.


Employe
# profession : char*
+ Employe(int, char)
+ ~Employe()
+ AfficherInfos() : void

DelegueSyndical

Syndicaliste

+ DelegueSyndical()
+ OrganiserReunion() : void

# nomSyndicat : char*
# numMembre : int
+ Syndicaliste()
+ ~Syndicaliste()

Figure 5.12 : exemple dhritage multiple


class Employe : public Personne
{
public:
Employe(int = 1, char = '-');
~Employe();
void AfficherInfos();
protected:
char* profession;
};
...
class Syndicaliste
{
public:
Syndicaliste();
~Syndicaliste();
protected:
char* nomSyndicat;
int numMembre;
};
...

58 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

class DelegueSyndical : public Employe, public Syndicaliste


{
public:
DelegueSyndical();
void OrganiserReunion();
};
...

5.3.3

Relations entre classes de base et classe drive

Laction de drivation implique plusieurs relations entre les membres des classes de base et de la classe drive :
V recopie des membres de chacune des classes de base, conformment leur visibilit ;
V appel des constructeurs de chacune des classes de base, dans lordre des dclarations dhritage, avant lappel
du constructeur de la classe drive (SuperClasse1(), puis SuperClasse2(), puis SousClasse()), afin
dinitialiser les attributs hrits ;
V appel des destructeurs de chacune des classes de base, dans lordre inverse des dclarations dhritage, aprs
lappel du destructeur de la classe drive (~SousClasse(), puis ~SuperClasse2(), puis
~SuperClasse1()), afin de raliser les oprations ncessaires la destruction des lments hrits et qui
sont dfinies dans les super-classes.
Si rien nest explicitement spcifi, ce sont les constructeurs par dfaut des classes de base qui sont appels.
Dans le cas o une ou plusieurs classes de base ne possdent pas de constructeur par dfaut, ou quil est prfrable
de faire appel une version surcharge du constructeur, il faut alors spcifier explicitement lappel aux constructeurs
des classes de base en utilisant la syntaxe :
SousClasse::SousClasse(...)
: SuperClasse1(paramtres)
, SuperClasse2(paramtres)
, ...
{ /* code du constructeur */ }

5.3.4

Hritage virtuel

La sous-classe hrite des membres de chacune de ses super-classes. Dans le cas o plusieurs super-classes hritent
elles-mmes dune mme autre classe, on se trouve face un problme : certains membres se retrouvent en double
dans la sous-classe.
Ex. : La classe Syndicaliste drive en ralit de la classe Personne ; la classe Employe drive elle aussi de la
classe Personne. La classe DelegueSyndical, qui drive des classes Employe et Syndicaliste, retrouve donc
des doublons de membres de Personne.
Employe
# profession : char*

Personne

+ Employe(int, char)
+ ~Employe()
+ AfficherInfos() : void

DelegueSyndical

Syndicaliste

+ DelegueSyndical()
+ OrganiserReunion() : void

# age : int
# initiale : char
+ Personne(int, char)
+ AfficherInfos() : void

# nomSyndicat : char*
# numMembre : int
+ Syndicaliste()
+ ~Syndicaliste()

Figure 5.13 : exemple dun cas de conflit dans un hritage multiple

59 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

class Personne
{
public:
Personne(int = 0, char = '?');
void AfficherInfos();
protected:
int age;
char initiale;
};
...
class Employe : public Personne
{
public:
Employe(int = 1, char = '-');
~Employe();
void AfficherInfos();
protected:
char* profession;
};
...
class Syndicaliste : public Personne
{
public:
Syndicaliste();
~Syndicaliste();
protected:
char* nomSyndicat;
int numMembre;
};
...
class DelegueSyndical : public Employe, public Syndicaliste
{
public:
DelegueSyndical();
void OrganiserReunion();
};
...
int main(void)
{
DelegueSyndical dsynd1;
dsynd1.AfficherInfos(); // ambigut : s'agit-il de Employe::AfficherInfos() ou
// de Syndicaliste::AfficherInfos() (hrit directement
return 0;
// de Personne::AfficherInfos()) ?
}

Les problmes de conflits de membres peuvent tre nanmoins rsolus ponctuellement en utilisant loprateur
de rsolution de porte.
int main(void)
{
DelegueSyndical dsynd1;
dsynd1.Employe::AfficherInfos(); // c'est la version de Employe qui est appele
return 0;
}

Cependant, cette solution demeure insatisfaisante : lespace mmoire occup par un objet DelegueSyndical
nest pas optimis, et celui-ci possde 2 noms et 2 initiales, ce qui manque de cohrence ; de plus, deux appels
au constructeur de la classe Personne sont raliss, dabord Personne(1, '-') via le constructeur
Employe(), puis Personne() via le constructeur Syndicaliste().

60 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Il est alors gnralement prfrable de mettre en place un hritage virtuel aucun lien direct avec les mthodes
virtuelles et les classes abstraites qui permet de sassurer de navoir quune seule occurrence des membres
redondants hrits.
On dfinit un hritage virtuel en utilisant le modificateur virtual dans la dclaration dhritage suivant la syntaxe
class SousClasse : virtual mode_drivation SuperClasse {...};.
Nb : Lhritage virtuel nagit pas pour la classe elle-mme, mais uniquement pour les classes descendantes de la
classe qui porte la marque dhritage virtuel. En effet, celles-ci ne peuvent pas connatre les origines de leurs classe de
base et en consquence ne peuvent dtecter une situation de conflit dhritage de membres.
Ex. : Pour ne pas avoir de membres redondants dans la classe DelegueSyndical, il faut prciser que les classes
Employe et Syndicaliste hritent virtuellement de Personne.
class Employe : virtual public Personne // hritage virtuel
{
...
};
...
class Syndicaliste : virtual public Personne // hritage virtuel
{
...
};
...
class DelegueSyndical : public Employe, public Syndicaliste
{
...
};
...
int main(void)
{
DelegueSyndical dsynd1;
dsynd1.AfficherInfos(); // affichage: "age 0" | "initiale ?" | "profession n.c"
return 0;
}

Un seul appel au constructeur de la classe Personne est ralis : Personne() ; mme sil est bien fait appel
Employe() puis Syndicaliste().

Lhritage multiple reste peu utilis, car il est susceptible de gnrer des conflits, qui ne sont pas toujours facilement
rsolvables.
Les langages de programmation oriente objet plus rcents, comme Java ou C#, nautorisent pas lhritage multiple
pour ces raisons, et prfrent mettre en uvre le mcanisme des interfaces 1.

Notion dsignant dans ce cas un type de classe spcifique pouvant tre dfinie ainsi : une interface est une classe abstraite dont toutes les
mthodes sont virtuelles pures.
61 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

6 LA GNRICIT
6.1 PRINCIPES ET DFINITIONS
La gnricit dsigne le principe de dfinition dun modle de fonction, de mthode ou de classe, hors de toute
considration de type ou de taille (cas dun tableau). Cela permet ainsi de travailler avec des donnes gnriques, id est
pouvant correspondre nimporte quel type (types primitifs, complexes ou classes), en fonction de ses besoins.
Pour dfinir un paramtre gnrique, on utilise le mot-clef class, quelque soit le type futur qui sera associ ce
paramtre 1, suivant la dclaration class NomParametreGenerique.
Le nom dun paramtre gnrique suit les mmes rgles que les noms de variables, fonctions, attributs et mthodes.
Pour dfinir un modle quil sagisse de fonction, de mthode ou de classe il faut donc dclarer un ou plusieurs
paramtres gnriques juste avant la dclaration du modle, en utilisant le mot-clef template 2 suivant la syntaxe :
template <class NomParametreGenerique1, class NomParametreGenerique2, ...>
dclaration_modle { ... }

Une fois le modle compltement dfini, il peut tre utilis. Dans le cadre de chaque utilisation, il faut alors prciser
le type exact que doit prendre chaque paramtre gnrique, suivant la syntaxe :
nom_modle<type_paramtre_gnrique1, type_paramtre_gnrique2, ...>

On parle en ce cas dinstanciation du modle gnrique et les diffrentes utilisations du modle avec divers types de
paramtres gnriques constituent donc diffrentes instanciations du modle.
La gnricit peut tre applique une fonction, une mthode ou une classe. Cest le compilateur qui se charge de
crer toutes les mthodes, fonctions ou classes ncessaires, partir du modle dfini et des utilisations de ce modle
dans le programme compil. Un modle non instanci (/ non utilis) nest donc pas compil et est absent du
programme final.

6.2 LES MTHODES ET FONCTIONS GNRIQUES


Dfinir une fonction / mthode gnrique permet dappliquer un mme traitement des variables ou objets de type
non fix au dpart, soit donc applicable tout type de donnes (pour peu que le traitement appliqu ait du sens).
Ex. : template <class T> // dclaration d'un paramtre gnrique nomm T
type_fonction nomFonction(T nomParametre)
{
...
}

Nb : Le paramtre gnrique doit imprativement faire partie de la signature de la fonction 3 afin que diverses
surcharges diffrencies puissent par la suite tre gnres automatiquement.
La fonction / mthode peut alors tre instancie (/utilise) pour nimporte quel type de variables ou objets.

1
2
3

Il serait dailleurs bien difficile de prvoir les utilisations futures du modle.


Template (eng) Z modle (fr) ; on peut parler aussi de patron, ou gabarit.
Et pas du prototype, ce qui exclut donc le type de retour.
62 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : Soit une fonction permettant dafficher le contenu dun tableau, ainsi quune fonction permettant den trier le
contenu.
template <class T>
void afficher(T* tab, int taille)
{
for ( int i=0 ; i<taille ; i++ )
cout << tab[i] << " ";
cout << endl;
}
template <class T>
void trier(T* tab, int taille)
{
int indmin;
T tmp;
for ( int i=0 ; i<taille ; i++ ) {
indmin = i;
for ( int j=i+1 ; j<taille ; j++ )
if ( tab[indmin] > tab[j] ) indmin = j;
tmp = tab[i];
tab[i] = tab[indmin];
tab[indmin] = tmp;
}

int main(void)
{
int tab1[5] = {12, -5, 3, 34, 5};
float tab2[3] = {8.544, 7.2, -87.1};
char tab3[10] = "bonjour";
trier<int>(tab1, 5);
trier<float>(tab2, 3);
trier<char>(tab3, 7);
afficher<int>(tab1, 5); // affichage: "-5 3 5 12 34"
afficher<float>(tab2, 3); // affichage: "-87.1 7.2 8.544"
afficher<char>(tab3, 7); // affichage: "b j n o o r u"
return 0;
}

Le compilateur cre donc ici 3 versions de la fonction afficher(), pour T de type int, float et char :
c void afficher(int* tab, int taille) ;
c void afficher(float* tab, int taille) ;
c void afficher(char* tab, int taille).
ainsi que 3 versions de la fonction trier(), pour T de type int, float et char :
c void trier(int* tab, int taille) ;
c void trier(float* tab, int taille) ;
c void trier(char* tab, int taille).
Si le type du paramtre gnrique peut tre dduit sans quivoque par rapport au paramtre fourni dans lappel de la
fonction/mthode, il peut tre omis.
Ex. : template <class X>

X min(X val1, X val2)


{
if ( val1 < val2 ) return val1;
else return val2;
}

63 / 104

Programmation Oriente Objet > Langage C++ > Cours

int main(void)
{
cout << min(4, -5) << endl;
cout << min(-54.3, -5) << endl;
}

v1.5.4.2 27/05/2010

// X est un int
// X est un double

Les fonctions et mthodes gnriques peuvent tre surcharges par des fonctions et mthodes non-gnriques, ce qui
permet ainsi de prciser le comportement de la fonction / mthode pour un cas particulier de type de variables ou
dobjets.

6.3 LES CLASSES GNRIQUES


Les classes gnriques, appeles aussi classes paramtrables, permettent de dfinir un modle de classes 1 pouvant
tre appliqu avec divers types de variables ou dobjets.
NomParametreGenerique1,
NomParametreGenerique2,
...

NomClasse

Figure 6.1 : reprsentation dune classe gnrique


template <class NomParametreGenerique1, class NomParametreGenerique2, ...>
class NomClasse
{
...
};

Les diffrentes mthodes de la classe peuvent alors utiliser le ou les paramtres gnriques ainsi dfinis.
Ex. : Une classe gnrique ListeSimple permettant de grer une liste de variables ou dobjets quelconques.
template <class T>
class ListeSimple
{
public:
ListeSimple(int);
~ListeSimple();
void AddElement(const T&);
void Lister();
private:
int nbElements;
int taille;
T* elements;
};

Limplmentation des mthodes fait partie intgrante du modle de classes. Chaque dfinition de mthode, quelle
utilise le paramtre gnrique ou pas, doit donc spcifier nouveau les paramtres gnriques suivant la syntaxe :
template <class NomParametreGenerique1, class NomParametreGenerique2, ...>
NomClasse<NomParametreGenerique1, NomParametreGenerique2, ...>::NomMethode(...) {...}

Ex. : template <class T>

ListeSimple<T>::ListeSimple(int t)
{
this->nbElements = 0;
this->taille = t;
this->elements = new T[this->taille];
}

// appel du constructeur par dfaut de T

template <class T>


ListeSimple<T>::~ListeSimple()
{
delete[] this->elements;
}
1

Une classe tant dj elle-mme un modle, on parle aussi de mta-modle pour les classes gnriques.
64 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

template <class T>


void ListeSimple<T>::AddElement(const T& nouvelElement)
{
if ( this->nbElements < this->taille )
this->elements[this->nbElements++] = nouvelElement; // appel de l'oprateur
}
// = sur des objets T
template <class T>
void ListeSimple<T>::Lister()
{
for ( int i=0 ; i < this->nbElements ; i++ )
cout << this->elements[i] << endl; // appel de l'oprateur << sur un objet T
}

La classe gnrique ainsi dfinie peut donc tre instancie (/utilise) avec tout type de variables ou dobjets. Lorsque
le type des paramtres gnriques est parfaitement dfini, on parle alors de classe paramtre.
Ex. : Utilisation de la classe gnrique ListeSimple.
int main(void)
{
ListeSimple<int> data(10);
data.AddElement(2);
data.AddElement(4);
data.AddElement(6);
data.Lister();
ListeSimple<Personne> groupe(5);
groupe.AddElement(Personne(30, "joe"));
groupe.AddElement(Personne(22, "bob"));
groupe.AddElement(Personne(28, "ken"));
groupe.Lister();
return 0;
}

Nb : Lusage de la gnricit avec des objets imposent que leur classe puisse se conformer au modle et se
comporter sans ambigut. Cela peut pr-supposer par exemple que la classe possde un constructeur par dfaut, la
surcharge doprateurs tels que =, +, <<, ==, !=, etc.
Ex. : Linstanciation de ListeSimple avec la classe Personne impose pour celle-ci :
V lexistence du constructeur par dfaut Personne() (utilis dans le constructeur ListeSimple()) ;
V la rcriture de la surcharge de loprateur = (utilis dans AddElement()), celle cre automatiquement par
le compilateur ntant pas correcte ;
V lcriture de la surcharge de loprateur << (utilis dans Lister()).
Les classes gnriques peuvent tre surcharges par des instanciations dfinies, soit donc des classes pour
lesquelles le type des paramtres gnriques est donn. On utilise pour cela la syntaxe :
class NomClasse<type_paramtre_gnrique1, type_paramtre_gnrique2, ...>

Cela permet ainsi de prciser le comportement de la classe pour un cas particulier de type de variables ou dobjets.
Ex. : class ListeSimple<string>
{
...
};
ListeSimple<string>::ListeSimple(int t)
{
...
}
...

Les entits gnriques, lors de leur instanciation, sont parfois analyses par le prprocesseur, ce qui pose des
problmes lors de la compilation.
65 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Dans le cas dune classe gnrique dont la dclaration et la dfinition sont spares suivant le couple de fichiers
.h/.cpp, il faut positionner lintgralit du code de limplmentation des mthodes directement dans le fichier .h (en
revanche, inutile den faire des mthodes inline et de mettre le code dans la dclaration de la classe).
Les fonctions avec lesquelles est applique la classe gnrique ncessitent dtre dclares dans le .h, mme si
limplmentation doit en revanche rester dans le fichier .cpp (Ex. : la fonction de surcharge de loprateur <<).

66 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

7 LES EXCEPTIONS
7.1 INTRODUCTION
Dans le cadre de la fiabilisation dun programme, il est impratif de prvoir et de grer les erreurs dexcution et
situations anormales. Celles-ci pouvant tre de natures trs diverses, matrielles (Ex. : erreur daccs un fichier) ou
logicielles (Ex. : division par zro), et un programme tant gnralement constitu de diffrentes structures imbriques
(une procdure 1 appelant une autre procdure, qui elle-mme appelle une tierce procdure, etc.), cela soulve
plusieurs interrogations :
V Lerreur remet-elle en cause la suite de lexcution du programme (erreur fatale / irrcuprable), ou peut-elle
tre traite de manire poursuivre lexcution ?
V Sil y a traitement, est-il plus appropri de leffectuer bas niveau (procdure qui a dtect lerreur), ou bien
haut niveau (procdure appelante ou de niveau suprieur) ?
c bas niveau : lerreur ou situation anormale est dtectable, mais il est difficile de prdir le comportement
adopter, lequel par ailleurs peut ne pas tre toujours le mme, tre fonction de paramtres et conditions
grs par une autre procdure de lapplication, ou bien ncessiter lintervention de lutilisateur ;
c haut niveau : le traitement de lerreur est ralisable, mais il est difficile voire impossible de la dtecter.
Ex. : Erreur dexcution lors de louverture dun fichier (causes possibles : fichier inexistant, systme de fichiers
illisible, demande douverture en criture dun fichier en lecture seule, ).
void ouvrirFichier(char* nomFichier)
{
// ouvrirFichier() sait dtecter une erreur d'ouverture du fichier
// mais quel traitement raliser : demander ouvrir un autre fichier,
// crer un fichier du nom spcifi, terminer le programme, ... ?
}
int main(void)
{
char* nomFichier;
...
ouvrirFichier(nomFichier);
// main() sait comment ragir en cas de problme d'ouverture du fichier
// mais comment dtecter un tel problme ?
return 0;
}

Cette problmatique se traduit, pour chaque erreur dexcution ou situation anormale potentielle, par un traitement
selon lune des 3 stratgies suivantes :
V Lerreur provoque larrt complet du programme ;
V Lerreur est traite localement, et gnralement de manire transparente, par la procdure qui la dtecte ;
V Lerreur est signale la procdure appelante par la procdure qui la dtecte via un mcanisme permettant
de spcifier le type derreur (Ex. : retour dun code derreur).
En ce cas, lerreur est soit traite par la procdure appelante, soit est nouveau signale la procdure de
niveau suprieur laquelle a donc en charge le traitement de lerreur , soit signale la procdure de niveau
encore suprieur, etc. ; ce qui au plus haut niveau se caractrise par une interaction avec lutilisateur.
Le traitement dune erreur peut tre ralis par une structure de contrle (if () else), mais dans le cas dune
erreur qui nest pas traite localement mais doit tre signale la procdure appelante, cela nest pas toujours
1

Fonction ou mthode.
67 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

ralisable. Il est effectivement parfois dlicat de raliser haut niveau limportance et les consquences des erreurs
dexcution de bas niveau, et le traitement associ, sil y en a un, peut ne pas tre appropri.
Il est donc ncessaire de disposer dun mcanisme de communication entre les diffrents niveaux dune application.

7.2 DFINITIONS
Le terme exception dsigne le signal envoy une procdure par une autre procdure ayant dtect loccurrence
dune erreur dexcution ou dune situation anormale.
cette exception est associ un mcanisme qui permet de sassurer que lerreur dtecte puisse tre prise en compte
par la procdure appelante ou lune des procdures de niveau suprieur. Ce mcanisme est en ralit une nouvelle
structure de contrle, introduisant de nouveaux mots-clefs :
V Une procdure qui dtecte une erreur ou une situation anormale construit une exception et la
propage/signale/ lance (mot-clef throw) lintention de la procdure appelante ;
V Lorsquune procdure dsire tre capable de prendre en charge lexception quune procdure utilise
directement ou indirectement est susceptible de lancer, elle essaye dexcuter (mot-clef try) la procdure
en question ;
V Lexception potentielle est intercepte/ attrape (mot-clef catch) par la procdure appelante via un
gestionnaire dexception, lequel ralise alors le traitement appropri.
void procedureBasNiveau()
{
if ( erreur ) // condition(s) d'erreur
throw exception; // lancement d'une exception
}
void procedureHautNiveau()
{
try {
// code susceptible de lancer une exception
procedureBasNiveau();
// code jamais excut si la procdure de bas niveau lance une exception
...
}
catch (...) { // gestion de l'exception (les ... sont littral)
// traitement raliser en cas de lancement d'une exception
}
// poursuite de l'excution
...
}

Un bloc de code try doit tre immdiatement suivi dun bloc de code catch ().
Lorsquune exception est lance, la suite dinstructions du bloc try est interrompue, et lexcution passe
directement au gestionnaire dexception dcrit dans le bloc catch () qui dfinit le traitement de lexception, courtcircuitant ainsi les instructions restantes du bloc try qui ne seront jamais excutes.
Si des variables ont t dclares dans le bloc try, leur mmoire alloue est automatiquement libre avant
lexcution du bloc catch (). Si des objets ont t dclars dans le bloc try, leur destructeur est appel et leur
mmoire alloue est automatiquement libre avant lexcution du bloc catch ().
Une fois le bloc catch () excut, lexcution reprend son cours normal aux lignes dinstructions qui suivent.

7.3 IMPLMENTATION
7.3.1

Interception et gestion des exceptions

Linterception et la gestion dune exception sont ralises grce la structure de contrle try catch (), selon la
syntaxe :

68 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

try {
// code susceptible de lancer une exception
}
catch (...) { // gestion de tout type d'exception
// traitement raliser en cas de lancement d'une exception
}

Ex. : Une procdure de haut niveau appelle une procdure de bas niveau qui ncessite un paramtre entier de valeur
strictement positive pour sexcuter correctement ; si ce nest pas le cas, elle lance une exception.
void procedureBasNiveau(int x)
{
// x doit tre strictement positif sinon une exception est lance
}
void procedureHautNiveau(int xx)
{
cout << "avant l'exception" << endl;
try {
// code susceptible de lancer une exception
cout << "avant la procedure de bas niveau" << endl;
procedureBasNiveau(xx);
cout << "apres la procedure de bas niveau" << endl;
}
catch (...) { // prise en compte de tout type d'exception
// traitement raliser en cas de lancement d'exception
cout << "!probleme!" << endl;
}
// poursuite de l'excution
cout << "apres l'exception" << endl;
}
int main(void)
{
int nb;
cin >> nb;
// saisie de l'utilisateur devant tre strictement positive
procedureHautNiveau(nb);
return 0;
}

Si le nombre saisi par lutilisateur est suprieur 0, alors lexcution affiche : avant lexception / avant la
procdure de bas niveau / aprs la procdure de bas niveau / aprs lexception .
Si le nombre saisi par lutilisateur est infrieur ou gal 0, alors lexcution affiche : avant lexception /
avant la procdure de bas niveau / !probleme! / aprs lexception .
Lexception construite (via throw) est disponible sous la forme de nombre, de chane de caractres, dobjet, dobjet
ddi pour les exceptions, etc. et est gnralement porteuse dinformations sur lerreur qui a t dtecte. La procdure
qui attrape lexception peut rcuprer ces informations et les utiliser pour adapter le traitement lerreur dtecte.
De plus, la capacit dune exception tre disponible sous diffrentes formes permet une procdure de bas niveau
de gnrer plusieurs exceptions distinctes, diffrencies par leur type.
Lors de la gestion de lexception, les diffrents types dexceptions pouvant tre lances doivent tre filtrs en
construisant diffrents gestionnaires dexceptions spcialiss. Pour spcialiser un bloc catch (), il suffit de prciser
un paramtre, selon la mme syntaxe que les paramtres dentre dune procdure.
Les diffrentes spcialisations dexceptions sont mentionnes en spcifiant successivement autant de blocs
catch () que de types dexceptions diffrents grer. Le bloc catch (...) intercepte tout type dexception.
try {
//
}
catch
//
//
}

code susceptible de lancer une exception


(type_exception varExcept) { // gestion des exceptions du type type_exception
traitement raliser en cas de lancement d'exception de type type_exception
le paramtre varExcept peut tre utilis pour rcuprer plus d'informations

69 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : La procdure de bas niveau peut lancer plusieurs types dexceptions, afin de renseigner sur lerreur dtecte :
exception de type int lorsque la valeur du paramtre est strictement ngative, exception de type char* lorsque la
valeur du paramtre est nulle.
...
void procedureHautNiveau(int xx)
{
try {
procedureBasNiveau(xx);
}
catch (int code_erreur) { // exception de type int
cout << "!error " << code_erreur << "!" << endl;
}
catch (char* message) { // exception de type char*
cout << message << endl;
}
catch (...) { // exceptions d'autres types
cout << "!probleme inconnu!" << endl;
}
}
...

Lors du lancement dune exception, les diffrents gestionnaires catch () sont examins lun aprs lautre, dans
lordre dans lequel ils sont dclars, jusqu en trouver un capable de grer le type dexception qui a t lance ; cest-dire un gestionnaire dont le paramtre est compatible avec le type de lexception 1.
Si cest le cas, alors lexception est considre comme ayant t attrape, et aucun autre gestionnaire catch () ne
peut tre excut, mme si le type dexception correspond.
Une fois le bloc catch () pleinement trait, lexcution se poursuit linstruction qui suit le dernier gestionnaire
dexceptions.
Une procdure peut aussi dcider de ne traiter que certains types dexceptions en particulier ; les autres sont traits
par une ou plusieurs tierces procdures dautres niveaux (soit plus haut, soit plus bas entre la procdure courante et la
procdure qui a lanc lexception). Pour cela, il suffit de ne mentionner que les gestionnaires dexceptions dsirs.
Ex. : La procdure de haut niveau ne prend en charge quune partie des exceptions pouvant tre lances par la
procdure de bas niveau les exceptions de type int ; les autres types dexceptions sont attraps plus haut niveau.
...
void procedureHautNiveau(int xx)
{
try {
procedureBasNiveau(xx);
}
catch (int code_erreur) { // exception de type int
cout << "!error " << code_erreur << "!" << endl;
}
// aucun autre type d'exception attrap ici
}
int main(void)
{
int nb;
cin >> nb;
try {
procedureHautNiveau(nb);
}
catch (char* message) { // exception de type char*
cout << "-" << message << "-" << endl;
}
}
1

return 0;

Cette compatibilit peut tre ralise par des conversions implicites et les proprits de lhritage et du polymorphisme.
70 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Dans le cas o une exception lance nest attrape par aucune autre procdure (aucune prise en compte dexception
via try catch () dfinie, ou aucun gestionnaire catch () compatible), une erreur dexcution 1 est gnre 2 via
la fonction prdfinie terminate() (espace de noms std).
Il est possible de modifier le comportement par dfaut de lapplication vis--vis de toute exception lance mais non
attrape, en utilisant la fonction set_terminate() (espace de noms std), selon la syntaxe
set_terminate(fonction).
Ex. : Modification du traitement par dfaut pour les exceptions lances mais non attrapes.
void termProc()
{
cout << "!exception non attrapee!" << endl;
exit (-1);
// on n'oublie pas de quitter le programme en signalant une erreur
}
void procedureBasNiveau(int x)
{
...
}
void procedureHautNiveau(int xx)
{
set_terminate(termProc); // redfinition du comportement en cas d'exception
// non attrape
try {
procedureBasNiveau(xx);
}
catch (int code_erreur) { // seul ce type d'exception est attrap
cout << "!error " << code_erreur << "!" << endl;
}
// en cas de valeur nulle pour xx, une exception de type char* est lance
// comme celle-ci n'est pas attrape, une erreur d'excution est gnre
// et termProc() est alors excut
procedureBasNiveau(-1); // aucun type d'exception attrap
// comme aucune exception n'est attrape, il y a erreur d'excution
// dans tous les cas o xx n'est pas strictement positif
}
int main(void)
{
int nb;
cin >> nb;
procedureHautNiveau(nb);
return 0;
}

7.3.2

Lancement des exceptions

Le lancement dune exception est ralise grce linstruction throw, selon la syntaxe throw exception.
Gnralement le lancement dune exception est subordonn au rsultat dun test dont le but est de dtecter lerreur ou
la situation anormale.
if ( erreur ) // condition(s) d'erreur
throw exception; // lancement de l'exception

Ex. : Une procdure de haut niveau appelle une procdure de bas niveau qui ncessite un paramtre de valeur
positive pour sexcuter correctement ; si ce nest pas le cas, elle lance une exception : exception de type int pour une
valeur du paramtre strictement ngative, exception de type char* pour une valeur du paramtre nulle.

1
2

Erreur dexcution (fr) Z Runtime Error (eng).


Lutilisation de la procdure susceptible de signaler une exception ne gnre une erreur dexcution que si une exception est lance, sinon
lexcution suit un cours parfaitement normal.
71 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

void procedureBasNiveau(int x)
{
if ( x < 0 )
throw -1; // lancement d'une exception de type int
if ( x == 0 )
throw (char*)"!valeur nulle!"; // lancement d'une exception de type char*
}
void procedureHautNiveau(int xx)
{
...
}
...

Comme il est dlicat voire impossible de savoir quels types dexceptions est susceptible de gnrer une procdure 1,
on le prcise gnralement dans son en-tte, la suite du prototype en utilisant le mot-clef throw suivant la syntaxe
2
throw (type_exception1, type_exception2, ) .
Ex. : La procdure de bas niveau peut lancer uniquement des exceptions de type int et char*, afin de renseigner
sur lerreur dtecte.
void procedureBasNiveau(int x) throw (int, char*)
{
...
}
...

Lorsque len-tte dune procdure ne mentionne aucun type dexception, cest quelle peut en fait lancer tout type
dexception.
Pour spcifier quaucune exception ne peut tre gnre, on prcise simplement throw () (sans paramtre) dans
len-tte.
Lorsquune procdure lance une exception non dclare dans len-tte, cela revient en fait au cas dune erreur
dexcution non prvue et donc non gre. Une fonction spcifique est alors excute : il sagit de la fonction
unexpected() (espace de noms std), dont le comportement par dfaut est dexcuter un traitement qui en dfinitif
appelle la fonction terminate().
Il est possible de modifier ce comportement par dfaut vis--vis de toute exception lance mais non dclare en
utilisant la fonction set_unexpected() (espace de noms std), selon la syntaxe set_unexpected(fonction).
Ex. : Modification du traitement par dfaut pour les exceptions lances mais non dclares.
void termProc()
{
cout << "!exception non attrapee!" << endl;
exit (-1); // sortie avec retour d'un code d'erreur
}
void unexProc()
{
cout << "!exception non declaree!" << endl;
exit (-1); // sortie avec retour d'un code d'erreur
}
void procedureBasNiveau(int x) throw (int) // seul un type d'exception est dclar
{
...
}

1
2

Lutilisateur dune procdure nest pas obligatoirement voire mme peu souvent le dveloppeur de la procdure.
Cependant, la dclaration des exceptions quune procdure laisse chapper ne fait partie ni de son prototype, ni de sa signature.
72 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

void procedureHautNiveau(int xx)


{
set_terminate(termProc); // redfinition du comportement en cas d'exception
// non attrape
set_unexpected(unexProc); // modification du comportement en cas d'exception
// non dclare
try {
procedureBasNiveau(xx);
}
catch (int code) {
cout << "!" << code << "!" << endl;
}
catch (char* message) {
cout << message << endl;
}
catch (...) { // exceptions d'autres types
cout << "!probleme inconnu!" << endl;
}
// tous les types d'exceptions sont attraps
// en cas de valeur nulle pour xx, une exception de type char* est lance
// mais comme celle-ci n'est pas dclare, une erreur d'excution est gnre
// et unexProc() est alors excut
procedureBasNiveau(-1); // aucun type d'exception attrape
// comme aucune exception n'est attrape, une erreur d'excution est gnre
// dans tous les cas o xx n'est pas strictement positif
// et termProc() est alors excut
}
int main(void)
{
int xx;
cin >> xx;
procedureHautNiveau(xx);
return 0;
}

73 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

A MOTS-CLEFS DU LANGAGE C++


A.1 ORDRE ALPHABTIQUE
A
B
C
D
E
F
G
I
L
N
O
P
R
S
T
U
V
W

auto
bool
case
default
else
false
goto
if
long
new
operator
private
register
short
template
union
virtual
while

break
catch
delete
enum
float

char
do
explicit
for

inline

int

class
double
extern
friend

const

continue

static
true

struct
try

switch
typedef

NULL
protected
return
signed
this
unsigned
void

public
sizeof
throw
volatile

Les mots-clefs sont rservs, donc inutilisables comme nom de variable, fonction, classe, attribut ou mthode 1.

A.2 CATGORIES
A.2.1 Classes et membres
class
delete
friend
new
operator
template
this

Dclaration dune classe.


Destruction dun objet (libration de lespace mmoire).
Pour une classe, dfinition dune classe, mthode ou fonction amie (contournement de
lencapsulation pour accder aux membres de la classe).
Instanciation dun objet (rservation de lespace mmoire).
Prfixe gnrique aux surcharges doprateurs.
Dfinition de paramtres gnriques.
lintrieur dune mthode dune classe, rfrence lobjet de la classe auquel est appliqu la
mthode.

A.2.2 Modificateurs de visibilit de membres


private
protected
public

Visibilit limite la propre classe du membre.


Visibilit limite la propre classe du membre et ses sous-classes.
Aucune restriction de visibilit.

Mme si le langage C++ distingue la casse, il est dconseill dutiliser un nom, mme avec une casse distincte, proche dun mot-clef existant.
74 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

A.2.3 Types primitifs de variables et attributs


bool
char
double
float
int
short
void

Boolen (valeur true/false).


Caractre sur 1 octet (standard ASCII tendu).
Rel sur 8 octets.
Rel sur 4 octets.
Entier sur 4 octets.
Entier sur 2 octets.
Type vide (utilis uniquement pour dsigner un retour de fonction/mthode dun type
inutilis/inconnu).

A.2.4 Modificateurs dattributs


static

Attribut de classe (et non attribut dinstance) ; disponible mme sans disposer dinstance de la
classe, commun pour toutes les instances, valeur partage par toutes les instances.

A.2.5 Modificateurs de mthodes


const
explicit
static
virtual
= 0

Mthode constante, ne modifiant pas lobjet auquel est appliqu la mthode.


Constructeur tant obligatoirement appel explicitement (Classe objet = Classe();),
empchant ainsi notamment le compilateur de raliser des conversions implicites potentiellement
dangeureuses (Classe objet(valeur); / Classe objet = valeur;).
Mthode de classe (et non mthode dinstance) ; disponible mme sans disposer dinstance de la
classe, commune et partage par toutes les instances.
Mthode virtuelle ; pour les sous-classes, priorit au type dynamique (instanciation) plutt quau
type statique (dclaration).
Mthode virtuelle pure ; aucune implmentation donne dans la classe elle-mme, qui devient
alors une classe abstraite ; implmentation donne dans les sous-classes.

A.2.6 Modificateurs de variables et dattributs


V : variable de type primitif, O : objet, A : attribut de type primitif, Ao : attribut-objet.
V

auto

const

extern

long

register

signed

static

unsigned

volatile

Ao

X
X

Variable locale, qui nexiste que durant lexcution du bloc de code de


dclaration par dfaut.
Variable de valeur constante initialise une seule fois et qui ne peut pas
tre modifie lors de lexcution.
Dclaration partage par plusieurs fichiers source ; sa dure de vie est
celle dune dclaration globale (cf. static).
Variable dont la taille est double.
Variable stocke dans lun des registres du processeur, et dont les accs
sont ainsi optimiss (Nb : amlioration des performances non garantie).
Variable en format numrique sign, utilisant le bit de poids fort en guise
de signe (0 : positif, 1 : ngatif) ; chelle de valeurs centre autour de 0
(types numriques uniquement, cf. unsigned) par dfaut.
Variable locale dont la valeur est conserve entre deux appels de la
fonction (cf. auto).
Variable en format numrique non sign, utilisant tous les bits pour la
valeur ; dbut de lchelle de valeurs partir de 0 (types numriques
uniquement, cf. signed).
Variable sauvegarde uniquement en mmoire vive, et qui nest jamais
buffrise ; sa valeur instantane est ainsi assure lors de laccs par
diverses fonctions, lorsque celles-ci sont susceptibles den modifier la
valeur et que le programme ne peut le prvoir la compilation.

75 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

A.2.7 Modificateurs de fonctions et de mthodes


inline

Dfinition dune fonction-macro appel de la fonction remplac par son code source avant la
compilation par le prprocesseur.

A.2.8 Types de variables et attributs complexes


enum
struct
typedef
union

Dfinition dun type numr liste de mnmoniques alphanumriques de valeur entire et


successive (0, 1, 2, ).
Dfinition dun type structur regroupement de donnes de types diffrents (appels champs)
dans un seul ensemble.
Cration dun nouveau type sur la base dune variable utilisateur (variable simple, tableau,
pointeur, structure, etc.).
Dfinition dun type structur commun mise en commun dun espace mmoire accessible par
des donnes de types diffrents (appels champs).

A.2.9 Structures de contrle


break
case
continue
default
do
else
for
if
return
switch
while

Sortie de boucle ou de bloc de code.


Test multiple slection (cf. default, switch).
Poursuite de lexcution de la boucle (branchement litration suivante (test de continuit)).
Test multiple slection par dfaut (cf. case, switch).
Boucle avec une itration minimale (cf. while).
Test simple test conditionnel inverse (cf. if).
Boucle avec itration.
Test simple test conditionnel (cf. else).
Sortie du bloc de code avec ou sans valeur de retour.
Test multiple test de slection (cf. case, default).
Boucle avec une itration minimale (cf. do) ou aucune.

A.2.10 Gestion des exceptions


catch
throw
try

Capture et traitement dune exception (cf. try).


Lancement explicite dune exception, ou dclaration des types dexceptions quune
fonction/mthode est susceptible de lancer.
Dclaration dun bloc de code susceptible de lancer une exception (cf. catch).

A.2.11 Autres
false
goto
NULL
sizeof
true

Valeur boolenne fausse .


Branchement une tiquette (dsuet et dconseill).
Pointeur nul (pas despace mmoire rserv).
Renvoi de la taille en octets occupe par un type donn, ou par une variable (donc par son type).
Valeur boolenne vraie .

76 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

B DLIMITEURS ET OPRATEURS
B.1 DLIMITEURS
;
,
"
'
(
{
[

"
'
)
}
]

< >

Marque la fin dune ligne dinstruction ou dune dclaration.


Spare deux lments dune liste.
Dlimite une chane de caractres.
Encadre un caractre.
Encadre une liste de paramtres.
Dlimite un bloc dinstructions, ou une liste de valeurs dinitialisation.
Encadre la taille ou lindice dun tableau.
Encadre la dfinition de paramtres gnriques avant la dfinition dun modle, ou la dsignation
des types utiliser pour les paramtres gnriques lors dune utilisation du modle.

B.2 OPRATEURS
On distingue trois types doprateurs :
V unaire : 1 argument (1), syntaxe oprateur oprande ;
V binaire : 2 arguments (2), syntaxe oprande1 oprateur oprande2 ;
V ternaire : 3 arguments (3), syntaxe oprande1 oprateurA oprande2 oprateurB oprande3.

B.2.1 Oprateur daffectation


=
(op)=

Affectation. (2)
Oprateurs combins opration puis affectation (cf. B.2.4). (2)

B.2.2 Oprateurs arithmtiques


+
*
/
%
-

Addition. (2)
Soustraction. (2)
Multiplication. (2)
Division. (2)
Modulo reste de la division entire (division euclidienne) entre deux entiers. (2)
Oppos (positif/ngatif). (1)

B.2.3 Oprateurs binaires


&
|
!
^
~
<<
>>

ET logique (AND) vrai si les deux sont vrais / faux si lun des deux est faux. (2)
OU logique (OR) vrai si au moins lun des deux est vrai / faux si les deux sont faux. (2)
NON logique (NOT) vrai si faux / faux si vrai. (1)
OU logique exclusif (XOR) vrai si lun ou lautre est vrai mais pas les deux / faux si les deux sont
vrais ou si les deux sont faux. (2)
Complment un (inversion de tous les bits). (1)
Dcalage gauche du nombre de bits spcifis 1 bit : multiplication par 2, 2 bits : multiplication
par 4, etc. (2)
Dcalage droite du nombre de bits spcifis 1 bit : division par 2, 2 bits : division par 4, etc.. (2)

77 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

B.2.4 Oprateurs combins


Incrmentation (pr- et post-). (1)
Dcrmentation (pr- et post-). (1)
Addition et affectation. (2)
Soustraction et affectation. (2)
Multiplication et affectation. (2)
Division et affectation. (2)
Modulo et affectation. (2)
Dcalage gauche et affectation. (2)
Dcalage droite et affectation. (2)
ET logique bit--bit et affectation. (2)
OU logique bit--bit et affectation. (2)
OU logique exclusif bit--bit et affectation. (2)

++
-+=
-=
*=
/=
%=
<<=
>>=
&=
|=
^=

B.2.5 Oprateurs dvaluation dexpression


galit. (2)
Diffrence. (2)
Infriorit stricte. (2)
Infriorit ou galit. (2)
Supriorit stricte. (2)
Supriorit ou galit. (2)
ET logique (AND). (2)
OU logique (OR). (2)
NON logique (NOT). (1)

==
!=
<
<=
>
>=
&&
||
!

B.2.6 Oprateurs divers


type()
(type)
*
&
delete
delete[]
new
new[ ]
::
.
->
? :

Conversion explicite de type (transtypage, cast). (1)


Conversion de type (transtypage, cast). (1)
Oprateur dindirection (/dfrencement) accs au contenu. (1)
Oprateur dadresse accs au contenant. (1)
Destruction de variable/instance cre dynamiquement. (1)
Destruction de tableau de variables/instances cr dynamiquement. (1)
Cration dynamique de variable/instance. (1)
Cration dynamique de tableau de variables/instances. (1)
Oprateur de rsolution de porte. (2)
Accs un champ dune classe, dune structure ou dune union. (2)
Accs un champ dune classe, dune structure ou dune union pointe. (2)
Oprateur ternaire (excution conditionnelle simplifie). (3)

B.3 PRIORIT DES OPRATEURS ET DLIMITEURS


Le niveau de priorit des oprateurs et dlimiteurs est donn du plus prioritaire au moins prioritaire. Pour forcer les
priorits, il faut donc utiliser des parenthses.
+ prioritaire

::

delete

delete[]

(type)

const_cast

? : (3)

+ (2)
=

++var

- (2)
*=

[ ]

/=

( )
--var

type( )
* (1)

dynamic_cast
<<
%=

>>
+=

<

& (1)

->

var++

+ (1)

- (1)

reinterpret_cast
>

-=

<=
<<=

var--

new

sizeof

static_cast

.*
|

>=

==

!=

& (2)

>>=

&=

|=

^=

^
,

new[ ]

->*
&&

typeid
* ( 2)
||

prioritaire

(1) : oprateur unaire, (2) : oprateur binaire, (3) : oprateur ternaire.

78 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

C LA STL : LIBRAIRIE STANDARD


C.1 INTRODUCTION
Le langage C++, linstar du langage C, reste limit en oprations de base . La STL (Standard Template
Library 1) ou librairie standard , intgre la norme ISO (98), regroupe un ensemble de bibliothques et enrichit
ainsi considrablement le langage.
Au-del du gain certain en efficacit et en simplicit pour tout programmeur C++, lutilisation de la STL favorise la
portabilit ainsi que la maintenabilit.
La STL offre ainsi :
V une partie des fonctions systme des bibliothques standard du langage C (standard ANSI) ;
V des classes string (ASCII ou Unicode) ;
V des classes pour la gestion des structures de donnes (conteneurs, itrateurs et algorithmes) ;
V un ensemble de classes pour la gestion des flux dentres/sorties ;
V
Toutes les inclusions de fichiers den-tte de la STL sont ralises par convention sans prciser lextension .h. Cela
permet de ne pas avoir se proccuper de la manire dont est implmente la STL employe.

C.2 PRSENTATION
C.2.1 Les espaces de noms
Un espace de noms est un regroupement en un seul ensemble dentits diverses (classes, fonctions, types, variables
et constantes) ayant trait gnralement une mme thmatique 2.
La dclaration dun espace de noms se ralise laide du mot-clef namespace en implmentant les entits de
lespace dans un bloc de code associ suivant la syntaxe :
namespace NomEspaceNoms {
/* dclaration, dfinition, implmentation, ... des entits de l'espace de noms */
}

Lutilisation dun membre dun espace de noms implique que le nom de celui-ci soit mentionn :
V par prfixation du membre avec le nom de son espace de noms suivi de loprateur de rsolution de porte
(nom pleinement qualifi) ;
Ex. : NomEspaceNoms::membre
3
V par dclaration dans len-tte de lintgralit de lespace de noms ;
Ex. : using namespace NomEspaceNoms;
V par dclaration dans le code du membre de lespace de noms.
Ex. : using NomEspaceNoms::membre;
Lutilisation des units dorganisation que sont les espaces de noms vise classifier des lments de code source, et
permet ainsi de rduire les sources de conflits. Cependant, des conflits peuvent subsister lors dune utilisation en
dclaration dans len-tte.
1
2
3

Standard Template Library (eng) Z Librairie de modles standard (fr).


Un espace de noms se rapproche ainsi de la notion de paquetage, prsente dans les langages ADA et Java par exemple.
Un peu la manire dune inclusion de bibliothque.
79 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Il est noter quun espace de noms :


V peut tre imbriqu dans un autre (NomEspaceNoms1::NomEspaceNoms2::membre) ;
V peut tre dfini dans plusieurs fichiers sources distincts ;
V peut tre dfini par un alias (namespace MonEspaceNom NomEspaceNoms1::NomEspaceNoms2) ;
V ne propose malheureusement aucun caractre de visibilit spcifique ses membres.
Un espace de noms par dfaut existe ; il sagit de lespace de noms global, et na pas de nom. Pour accder ses
membres, on crit donc ::membre.
Tout espace de noms dfini est donc imbriqu implicitement dans lespace de noms par dfaut.
Lespace de noms standard std contient lintgralit des entits de la STL ; la dclaration using namespace std
ou la syntaxe std::membre est donc trs courante.

C.2.2 La gestion des chanes de caractres


La STL propose deux classes facilitant grandement la manipulation des chanes de caractres (bibliothque string) :
V string : pour les caractres cods sur 8 bits (ASCII tendu) ;
V wstring : pour les caractres cods sur 16 bits (Unicode).
Les classes type string ne sont ni plus ni moins que des classes stockant une chane de caractres et proposant
diverses mthodes afin de rendre la gestion de la chane la plus pratique et ergonomique qui soit, tout en masquant les
problmes inhrents ce type (gestion de la taille automatique, optimisation de lespace mmoire, etc.).
Voici une liste non-exhaustive des mthodes de la classe string :
string()
string(const string&)
string(char*)
string(char*, int)
string(const string&, int)
string& operator=(...)
string& assign(...)
char* c_str()
char* str()
char* data()
int size()
int length()
char operator[](int)
char at(int)
void clear()
bool empty()
string& operator+=(...)
string& append(...)
string& insert(...)
string& erase(...)
string& replace(...)
int find(...)
int rfind(...)
int compare(...)
string substr(int, int)

Constructeur par dfaut (gnralement, cre une chane de 20 caractres).


Constructeur de recopie.
Construction dun objet string partir dune chane de caractres.
Construction dun objet string partir des n premiers caractres dune
chane ou dun objet string dj cr ; si le nombre de caractres spcifi
est suprieur la taille de la chane source, la taille de lobjet string est
calque sur celle-ci.
Modification dun objet string.
Renvoi de la chane stocke ; la chane se termine par le caractre fin de
chane.
Renvoi du tableau de caractres stock ; le tableau ne se termine pas par le
caractre fin de chane.
Renvoi de la taille de la chane stocke dans lobjet string.
Renvoi du nime caractre de la chane stocke.
Renvoi du nime caractre de la chane stocke avec contrle de la
validit de lindice.
Effacement de la chane stocke.
Renvoi de TRUE si la chane est vide, FALSE sinon.
Concatnation de la chane stocke.
Insertion dans la chane stocke.
Effacement de caractres dans la chane stocke.
Remplacement de caractres dans la chane stocke.
Recherche de caractres dans la chane stocke.
Comparaison avec la chane stocke.
Extraction dune sous-chane.

C.2.3 Les structures de donnes


La gestion des structures de donnes est assure par le trio indissociable des concepts fondamentaux suivants :
V conteneur : stockage des donnes dans la structure ;
V itrateur : accs et parcours de la structure ;
V algorithme : fonction applicable la structure.

80 / 104

Programmation Oriente Objet > Langage C++ > Cours

C.2.3.1

v1.5.4.2 27/05/2010

Les conteneurs

Un conteneur est un objet qui reprsente une structure de donnes dynamique. En dautres termes, un conteneur 1
est un objet qui permet de stocker un ensemble dobjets du mme type.
Pour pouvoir tre utilis avec nimporte quel type dobjets, les conteneurs sont implments en tant que classes
gnriques 2, le paramtre correspondant au type dobjets que le conteneur doit stocker.
Il existe plusieurs types de conteneurs :
V conteneurs lmentaires : structures de donnes simples avec accs selon un index ;
c vecteur (vector) : tableau dynamique, stockage ordonn et accs index tout lment de la structure ;
c liste (list) : liste chane, stockage non-ordonn et accs au premier ou au dernier lment de la
structure ;
c DQ (deque) : liste accs prfrentiel premier dernier, stockage non-ordonn et accs au premier, au
dernier lment ou au milieu de la liste.
V conteneurs labors : structures de donnes bases sur un conteneur lmentaire ;
c pile (stack) : structure de donnes type LIFO (Last In First Out), le premier trait est le dernier arriv ;
c file (queue) : structure de donnes type FIFO (First In First Out), le premier trait est le premier arriv ;
c tas (priority_queue) : file priorit, le premier trait est le plus prioritaire.
V conteneurs associatifs : structures de donnes type (clef, lment) avec accs selon la clef, celle-ci pouvant
tre un objet.
c ensemble (set) : collection ordonne pour laquelle la clef est llment associ lui-mme ;
c table (map) : collection ordonne pour laquelle la clef et llment associ sont distincts.
Nb : On notera quil existe des versions multiples (multiset, multimap) des conteneurs associatifs
pour lesquels une mme clef permet daccder plusieurs lments.

C.2.3.2

Les itrateurs

Un itrateur est un objet qui permet daccder en lecture ou criture lun des lments de la structure de donnes,
ou bien de se dplacer au sein de cette structure ; un itrateur peut ainsi tre compar un pointeur qui permet de
parcourir un tableau et daccder son contenu.
Un itrateur peut ainsi proposer les oprations suivantes :
V drfrencement : accs en lecture ou criture de la valeur de llment courant ;
V dplacement : modification de llment courant (pas de sa valeur) en parcourant la structure en avant, en
arrire, ou de manire alatoire.

C.2.3.3

Les algorithmes

Un algorithme est une fonction applicable un conteneur afin de modifier son contenu ou dy accder, obtenir des
informations, grer le conteneur, etc. Lalgorithme fait usage des itrateurs pour raliser ses oprations.
Le type dalgorithmes utilisables avec chaque type de conteneurs dpend directement du conteneur considr.

1
2

On parle aussi parfois de collection.


cf. 6.3.
81 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

D CORRESPONDANCE UML ET C++


D.1 STRUCTURE STATIQUE
D.1.1 Classes
D.1.1.1

Classe

NomClasse : dclaration de la classe.


NomClasse

Figure D.1 : reprsentation UML dune classe

Fichier NomClasse.h :
class NomClasse
{
...
};

D.1.1.2

Classe abstraite

NomClasseItalique (classe abstraite) : aucun mot-clef ou modificateur existant en C++.


NomClasseAbstraite

Figure D.2 : reprsentation UML dune classe abstraite

Fichier NomClasseAbstraite.h :
class NomClasseAbstraite
{
...
};

D.1.1.3

Classe paramtrable

NomParametre (classe gnrique / patron) : utilisation du mcanisme de gnricit (template).


NomParametreGenerique1,
NomParametreGenerique2,
...

NomClasseParametrable

Figure D.3 : reprsentation UML dune classe paramtrable

82 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Fichier NomClasseParametrable.h :
template <class NomParametreGenerique1, class NomParametreGenerique2, ...>
class NomClasseParametrable
{
...
};

D.1.2 Paquetage
NomPaquetage : regroupement des entits appartenant au paquetage dans un espace de noms.

NomPaquetage
UneClasse

AutreClasse

Figure D.4 : reprsentation UML dun paquetage


namespace NomPaquetage
{
class UneClasse
{
...
};
class AutreClasse
{
...
};
};

D.1.3 Membres
D.1.3.1

Membre

nomAttribut : dclaration dune variable associe la classe ;


NomMethode(...) : dclaration dune fonction associe la classe.
NomClasse

nomAttribut : type_attribut
NomMethode(...) : type_mthode

Figure D.5 : reprsentation UML dune classe et de ses membres

Fichier NomClasse.h :
class NomClasse
{
type_attribut nomAttribut;
type_mthode NomMethode(...);
};

Attribut de type instance de classe / objet : cf. associations (D.2).

83 / 104

Programmation Oriente Objet > Langage C++ > Cours

D.1.3.2

v1.5.4.2 27/05/2010

Implmentation des mthodes

Fichier NomClasse.cpp :
#include "NomClasse.h"
type_mthode NomClasse::NomMethode(...)
{
...
}

D.1.3.3

Visibilit

(priv) : section private ;


# (protg) : section protected ;
+ (public) : section public.
NomClasse
- nomAttribut1Prive : type_attribut1
# nomAttribut2Protege : type_attribut2
+ nomAttribut3Public : type_attribut3
- NomMethode1Privee(...) : type_mthode1
# NomMethode2Protegee(...) : type_mthode2
+ NomMethode3Publique(...) : type_mthode3

Figure D.6 : reprsentation UML dune classe, de ses membres et de leur visibilit

Fichier NomClasse.h regroupement des types de visibilits par section ; ordre par convention : public /
protected / private ; dclaration hors section (au tout dbut) : private (par dfaut) :
class NomClasse
{
public:
type_attribut3 nomAttribut3Public;
type_mthode3 NomMethode3Publique(...);
protected:
type_attribut2 nomAttribut2Protege;
type_mthode2 NomMethode2Protegee(...);
private:
type_attribut1 nomAttribut1Prive;
type_mthode1 NomMethode1Privee(...);
};

D.1.3.4

Membre statique

nomMembreSouligne (statique / membre de classe) : modificateur static.


NomClasse
- nomAttributStatique : type_attribut
+ NomMethodeStatique(...) : type_mthode

Figure D.7 : reprsentation UML dune classe avec des membres statiques

Fichier NomClasse.h :
class NomClasse
{
private:
static type_attribut nomAttributStatique;
public:
static type_mthode NomMethodeStatique(...);
};

84 / 104

Programmation Oriente Objet > Langage C++ > Cours

D.1.3.5

v1.5.4.2 27/05/2010

Mthodes virtuelle et virtuelle pure

NomMethode (virtuelle) : modificateur virtual ;


NomMethodeItalique (virtuelle pure / abstraite) : modificateur virtual et initialisation = 0.
NomClasseAbstraite

+ NomMethodeVirtuelle(...) : virtual type_mthode


+ NomMethodeVirtuellePure(...) : virtual type_mthode

Figure D.8 : reprsentation UML dune classe avec une mthode virtuelle et une mthode virtuelle pure

Fichier NomClasseAbstraite.h :
class NomClasseAbstraite
{
public:
virtual type_mthode NomMethodeVirtuelle(...);
virtual type_mthode NomMethodeVirtuellePure(...) = 0;
};

D.2 ASSOCIATIONS
Utilisation dune instance dune classe par une autre classe en tant quattribut-objet.
Plusieurs cas possibles : association simple, agrgation et composition.
Nb : Pas de rgles respecter imprativement, juste des conventions de codage visant respecter les concepts POO.

D.2.1 Association simple


Utilisation dune instance dune classe par une autre classe (a besoin de / ncessite) en tant quattribut-objet.
Aucune responsabilit vis--vis de la cration de linstance ou de la destruction de linstance.
ClasseUtilisatrice

rle CU

rle CI

ClasseNecessitee

Figure D.9 : reprsentation UML dune association

D.2.1.1

Association unidirectionnelle 1-1

ClasseA

monB

ClasseB

Figure D.10 : reprsentation UML dune association unidirectionnelle 1-1

Implmentation :
Pour la classe utilisatrice (ClasseA), dclaration en dynamique dun objet de la classe ncessite (ClasseB) en tant
quattribut dans la dclaration de classe (.h).
Initialisation de lobjet par rcupration dune rfrence externe la classe utilisatrice via lune de ses mthodes,
gnralement le constructeur (.cpp).
Fichier ClasseA.h :
#include "ClasseB.h"
class ClasseA
{
public:
ClasseA(ClasseB*);
private:
ClasseB* monB;
};

Fichier ClasseB.h :
class ClasseB
{
...
};

85 / 104

Programmation Oriente Objet > Langage C++ > Cours

Fichier ClasseA.cpp :

v1.5.4.2 27/05/2010

Fichier ClasseB.cpp :

#include "ClasseA.h"

#include "ClasseB.h"
...

ClasseA::ClasseA(ClasseB* b)
{
monB = b;
}

Autre implmentation :
Pour la classe utilisatrice (ClasseA), dclaration du type class de lobjet + dclaration en dynamique dun objet de
la classe ncessite (ClasseB) en tant quattribut dans la dclaration de classe (.h).
Initialisation de lobjet par rcupration dune rfrence externe la classe utilisatrice via lune de ses mthodes,
gnralement le constructeur (.cpp).
Fichier ClasseA.h :

Fichier ClasseB.h :

class ClasseB;

class ClasseB
{
...
};

class ClasseA
{
/* idem */
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
#include "ClasseB.h"

#include "ClasseB.h"
...

/* idem */

D.2.1.2

Association unidirectionnelle 1-plusieurs

ClasseA

mesB
*

ClasseB

Figure D.11 : reprsentation UML dune association unidirectionnelle 1-plusieurs

Implmentation :
Pour la classe utilisatrice (ClasseA), dclaration en dynamique dun tableau dobjets de la classe ncessite
(ClasseB) en tant quattribut dans la dclaration de classe (.h).
Initialisation de chaque objet du tableau par rcupration dune rfrence externe la classe utilisatrice via lune de
ses mthodes, gnralement le constructeur (.cpp).
Fichier ClasseA.h :
#include "ClasseB.h"
#define nombre 10

Fichier ClasseB.h :
class ClasseB
{
...
};

class ClasseA
{
public:
ClasseA(ClasseB*[]);
private:
ClasseB* mesB[nombre];
};

Fichier ClasseA.cpp :
#include "ClasseA.h"

Fichier ClasseB.cpp :
#include "ClasseB.h"
...

ClasseA::ClasseA(ClasseB* bs[])
{
for ( int i=0 ; i<nombre ; i++ )
mesB[i] = bs[i];
}

86 / 104

Programmation Oriente Objet > Langage C++ > Cours

D.2.1.3

v1.5.4.2 27/05/2010

Association bidirectionnelle

ClasseA

monA

monB

ClasseB

Figure D.12 : reprsentation UML dune association bidirectionnelle

Implmentation :
Pour chaque classe, dclaration du type class de lobjet + dclaration en dynamique dun objet de lautre classe en
tant quattribut dans la dclaration de classe (.h).
Pour chaque classe, initialisation de lobjet par rcupration dune rfrence externe la classe via lune de ses
mthodes, sauf le constructeur (.cpp).
Fichier ClasseA.h :

Fichier ClasseB.h :

class ClasseB;

class ClasseA;

class ClasseA
{
public:
ClasseA();
void UneMethodeA(ClasseB*);
private:
ClasseB* monB;
};

class ClasseB
{
public:
ClasseB();
void UneMethodeB(ClasseA*);
private:
ClasseA* monA;
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
#include "ClasseB.h"
#include <stddef.h>

#include "ClasseB.h"
#include "ClasseA.h"
#include <stddef.h>

ClasseA::ClasseA()
{
monB = NULL;
}

ClasseB::ClasseB()
{
monA = NULL;
}

void ClasseA::UneMethodeA(Classeb* b)
{
monB = b;
}

void ClasseB::UneMethodeB(ClasseA* a)
{
monA = a;
}

Nb : Un pointeur NULL est un pointeur non-initialis ; le mot-clef NULL est dfini dans la bibliothque stddef.h.

D.2.1.4

Association rflexive

ClasseA

monPropreA

Figure D.13 : reprsentation UML dune association rflexive

Implmentation :
Dclaration en dynamique dun objet de la mme classe en tant quattribut dans la dclaration de classe (.h).
Initialisation de lobjet par rcupration dune rfrence externe la classe via lune de ses mthodes, sauf le
constructeur (.cpp).
Fichier ClasseA.h :
class ClasseA
{
public:
ClasseA();
void UneMethodeA(ClasseA*);
private:
ClasseA* monPropreA;
};

87 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Fichier ClasseA.cpp :
#include "ClasseA.h"
#include <stddef.h>
ClasseA::ClasseA()
{
monPropreA = NULL;
}
void ClasseA::UneMethodeA(ClasseA* a)
{
monPropreA = a;
}

D.2.2 Agrgation
Utilisation dune instance dune classe par une autre classe en tant quattribut-objet avec un couplage fort et des
dures de vies distinctes (est constitu de / est fait de / fait partie de) ; appele aussi agrgation par rfrence.
Responsabilit vis--vis de la cration de linstance, mme si celle-ci reste partageable avec dautres instances
(mme classe ou autre classe) ; responsabilit vis--vis de la destruction de linstance pas obligatoire mais fortement
conseille.
ClasseAgregat

rle

rle

ClasseAgregee

Figure D.14 : reprsentation UML dune agrgation

D.2.2.1

Agrgation 1-1

ClasseA

monB

ClasseB

Figure D.15 : reprsentation UML dune agrgation 1-1

Implmentation :
Pour la classe agrgat (ClasseA), dclaration en dynamique (nda : par rfrence ) dun objet de la classe agrge
(ClasseB) en tant quattribut dans la dclaration de classe (.h).
Instanciation explicite de lobjet + destruction explicite (sil y a) dans les mthodes de la classe agrgat,
gnralement le constructeur et le destructeur respectivement (.cpp).
Fichier ClasseA.h :
#include "ClasseB.h"
class ClasseA
{
public:
ClasseA();
~ClasseA();
private:
ClasseB* monB;
};

Fichier ClasseA.cpp :
#include "ClasseA.h"

Fichier ClasseB.h :
class ClasseB
{
...
};

Fichier ClasseB.cpp :
#include "ClasseB.h"
...

ClasseA::ClasseA()
{
monB = new ClasseB();
}
ClasseA::~ClasseA()
{
delete monB;
}

88 / 104

Programmation Oriente Objet > Langage C++ > Cours

D.2.2.2

v1.5.4.2 27/05/2010

Agrgation 1-plusieurs
mesB
*

ClasseA

ClasseB

Figure D.16 : reprsentation UML dune agrgation 1-plusieurs

Implmentation :
Pour la classe agrgat (ClasseA), dclaration en dynamique (nda : par rfrence ) dun tableau dobjets de la
classe agrge (ClasseB) en tant quattribut dans la dclaration de classe (.h).
Instanciation explicite de chaque objet du tableau + destruction explicite (sil y a) dans les mthodes de la classe
agrgat, gnralement le constructeur et le destructeur respectivement (.cpp).
Fichier ClasseA.h :

Fichier ClasseB.h :

#include "ClasseB.h"

class ClasseB
{
public:
ClasseB();
};

#define nombre 10
class ClasseA
{
public:
ClasseA();
~ClasseA();
private:
ClasseB* mesB[nombre];
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"

#include "ClasseB.h"

ClasseA::ClasseA()
{
for ( int i=0 ; i<nombre ; i++ )
mesB[i] = new ClasseB();
}

ClasseB::ClasseB()
{
...
}

ClasseA::~ClasseA()
{
for ( int i=0 ; i<nombre ; i++ )
delete mesB[i];
}

D.2.2.3

Agrgation navigable

ClasseA

monA

monB

ClasseB

Figure D.17 : reprsentation UML dune agrgation navigable

Implmentation :
Pour chaque classe, dclaration du type class de lobjet + dclaration en dynamique (nda : par rfrence ) dun
objet de lautre classe en tant quattribut dans la dclaration de classe (.h).
Pour la classe agrgat (ClasseA), instanciation explicite de lobjet + destruction explicite (sil y a) dans les
mthodes de la classe agrgat, gnralement le constructeur et le destructeur respectivement (.cpp).
Pour la classe agrge (ClasseB), initialisation de lobjet par rcupration dune rfrence externe la classe via
lune de ses mthodes, gnralement le constructeur (.cpp).

89 / 104

Programmation Oriente Objet > Langage C++ > Cours

Fichier ClasseA.h :

v1.5.4.2 27/05/2010

Fichier ClasseB.h :

class ClasseB;

class ClasseA;

class ClasseA
{
public:
ClasseA();
~ClasseA();
private:
ClasseB* monB;
};

class ClasseB
{
public:
ClasseB(ClasseA*);
private:
ClasseA* monA;
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
#include "ClasseB.h"

#include "ClasseB.h"
#include "ClasseA.h"

ClasseA::ClasseA()
{
monB = new ClasseB(this);
}

ClasseB::ClasseB(ClasseA* a)
{
monA = a;
}

ClasseA::~ClasseA()
{
delete monB;
}

D.2.2.4

Agrgation rflexive

ClasseA

monPropreA

Figure D.18 : reprsentation UML dune agrgation rflexive

Implmentation :
Dclaration en dynamique (nda : par rfrence ) dun objet de la mme classe en tant quattribut dans la
dclaration de classe (.h).
Instanciation explicite dans lune de ses mthodes, sauf le constructeur, + destruction explicite (sil y a) dans une
mthode, gnralement le destructeur (.cpp).
Fichier ClasseA.h :
class ClasseA
{
public:
ClasseA();
~ClasseA();
void UneMethodeA();
private:
ClasseA* monPropreA;
};

Fichier ClasseA.cpp :
#include "ClasseA.h"
#include <stddef.h>
ClasseA::ClasseA()
{
monPropreA = NULL;
}
ClasseA::~ClasseA()
{
if ( monPropreA != NULL )
delete monPropreA;
}
void ClasseA::UneMethodeA()
{
monPropreA = new ClasseA();
}

90 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

D.2.3 Composition
Utilisation dune instance dune classe par une autre classe en tant quattribut-objet avec un couplage fort et des
dures de vies identiques (est compos de) ; appele aussi agrgation par valeur.
Responsabilit complte vis--vis de la cration de linstance ainsi que de la destruction de linstance ; instance
partageable avec aucune autre instance (mme classe ou autre classe).
ClasseComposite

rle

rle

ClasseComposant

Figure D.19 : reprsentation UML dune composition

D.2.3.1

Composition 1-1

ClasseA

monB

ClasseB

Figure D.20 : reprsentation UML dune composition 1-1

Implmentation :
Pour la classe composite (ClasseA), dclaration en statique (nda : par valeur ) dun objet de la classe composant
(ClasseB) en tant quattribut dans la dclaration de classe (.h).
Instanciation implicite de lobjet dans le constructeur, via le constructeur par dfaut de la classe composant, +
destruction implicite dans le destructeur, via le destructeur de la classe composant (.cpp) ; ventuellement,
instanciation explicite de lobjet dans la liste dinitialisation du constructeur, via une surcharge du constructeur de la
classe composant (.cpp).
Fichier ClasseA.h :
#include "ClasseB.h"
class ClasseA
{
private:
ClasseB monB;
};

Fichier ClasseA.cpp :
#include "ClasseA.h"
...

Fichier ClasseB.h :
class ClasseB
{
public:
ClasseB();
};

Fichier ClasseB.cpp :
#include "ClasseB.h"
ClasseB::ClasseB()
{
...
}

Nb : Possibilit de dclarer en dynamique (plutt quen statique) lobjet de la classe composant en tant quattribut
dans la dclaration de classe (.h), instanciation explicite dans le constructeur + destruction explicite dans le destructeur
(.cpp).
Reprsentation alternative : classe imbrique d instance partageable avec autre instance (mme classe ou autre
classe) + classe composant utilisable avec aucune autre classe.
ClasseComposite
ClasseComposant

Figure D.21 : reprsentation UML dune composition sous forme de classe imbrique

Implmentation :
Pour la classe composite (ClasseA), dclaration + dfinition de la classe composant (ClasseB), puis dclaration en
statique (nda : par valeur ) dun objet de la classe composant en tant quattribut dans la dclaration de classe (.h).
Instanciation implicite de lobjet dans le constructeur, via le constructeur par dfaut de la classe composant, +
destruction implicite dans le destructeur, via le destructeur de la classe composant (.cpp) ; ventuellement,

91 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

instanciation explicite de lobjet dans la liste dinitialisation du constructeur, via une surcharge du constructeur de la
classe composant (.cpp).
Fichier ClasseA.h :

Fichier ClasseA.cpp :

class ClasseA
{
private:
class ClasseB
{
ClasseB() {...}
};
ClasseB monB;
};

D.2.3.2

#include "ClasseA.h"
...

Composition 1-plusieurs

ClasseA

mesB
*

ClasseB

Figure D.22 : reprsentation UML dune composition 1-plusieurs

Implmentation :
Pour la classe composite (ClasseA), dclaration en statique (nda : par valeur ) dun tableau dobjets de la classe
composant (ClasseB) en tant quattribut dans la dclaration de classe (.h).
Instanciation implicite de chaque objet du tableau dans le constructeur, via le constructeur par dfaut de la classe
composant, + destruction implicite dans le destructeur, via le destructeur de la classe composant (.cpp).
Fichier ClasseA.h :

Fichier ClasseB.h :

#include "ClasseB.h"

class ClasseB
{
public:
ClasseB();
};

#define nombre 10
class ClasseA
{
private:
ClasseB mesB[nombre];
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
...

#include "ClasseB.h"
ClasseB::ClasseB()
{
...
}

D.3 SPCIALISATIONS / GNRALISATIONS


Spcialisation : dune super-classe vers une sous-classe ;
Gnralisation : dune sous-classe vers une super-classe.
spcialisation

ClasseGeneralisee

ClasseSpecialisee

gnralisation

Figure D.23 : reprsentation UML dune spcialisation / gnralisation

92 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

D.3.1 Spcialisation partir dune classe


ClasseG

ClasseS

Figure D.24 : reprsentation UML dune spcialisation partir dune classe

Implmentation :
Utilisation du mcanisme de lhritage avec le mode de drivation adquat (private / protected / public).
Fichier ClasseG.h :

Fichier ClasseS.h :

class ClasseG
{
...
};

#include "ClasseG.h"
class ClasseS : mode_drivation ClasseG
{
...
};

D.3.2 Spcialisation partir de plusieurs classes


ClasseG1
ClasseS
ClasseG2

Figure D.25 : reprsentation UML dune spcialisation partir de plusieurs classes

Implmentation :
Utilisation du mcanisme de lhritage multiple avec le mode de drivation adquat pour chaque super-classe
(private / protected / public).
Fichier ClasseG1.h :

Fichier ClasseG2.h :

class ClasseG1
{
...
};

class ClasseG2
{
...
};

Fichier ClasseS.h :
#include "ClasseG1.h"
#include "ClasseG2.h"
class ClasseS : mode_drivationG1 ClasseG1, mode_drivationG2 ClasseG2 {
...
};

D.4 CLASSE DASSOCIATION


volution dune association vers le concept de classe, possdant la fois les caractristiques dune association et
celles dune classe.
ClasseA

monB

monA

ClasseB

ClasseAB

Figure D.26 : reprsentation UML dune classe dassociation

93 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Implmentation :
Pour la classe dassociation (ClasseAB), dclaration comme une classe classique + dclaration en dynamique dun
objet de chaque classe associe (ClasseA et ClasseB) en tant quattributs dans la dclaration de classe (.h)
Pour chacune des classes associes, au regard de la navigabilit, dclaration en tant quattribut (.h) + initialisation
(.cpp) dun objet de lautre classe comme dans le cas dune association simple.
Fichier ClasseA.h :

Fichier ClasseB.h :

class ClasseB;

class ClasseA;

class ClasseA
{
public:
ClasseA();
void UneMethodeA(ClasseB*);
private:
ClasseB* monB;
};

class ClasseB
{
public:
ClasseB();
void UneMethodeB(ClasseA*);
private:
ClasseA* monA;
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
#include "ClasseB.h"
#include <stddef.h>

#include "ClasseB.h"
#include "ClasseA.h"
#include <stddef.h>

ClasseA::ClasseA()
{
monB = NULL;
}

ClasseB::ClasseB()
{
monA = NULL;
}

void ClasseA::UneMethodeA(ClasseB* b)
{
monB = b;
}

void ClasseB::UneMethodeB(ClasseA* a)
{
monA = a;
}

Fichier ClasseAB.h :
#include "ClasseA.h";
#include "ClasseB.h";
class ClasseAB
{
public:
ClasseAB(ClasseA*, ClasseB*);
private:
ClasseA* unA;
ClasseB* unB;
};

Fichier ClasseAB.cpp :
#include "ClasseAB.h"
ClasseAB::ClasseAB(ClasseA* a, ClasseB* b)
{
unA = a;
unB = b;
}

D.5 DPENDANCES
Instanciation, utilisation ou tout autre besoin smantique entre deux classes ne conditionnant ni napportant de
signification quant la structure interne de ces classes (utilise / est abstraction de / est li / a permission sur).
Concept trs gnral pouvant signifier diffrents types de relations entre une classe A et une classe B, gnralement
caractris par lusage dun strotype ; exemples :

94 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

V linstanciation dun objet de B dans une mthode de A autre que le constructeur de A (strotype
<<instanciate>>) ;
V lutilisation dune rfrence sur une instance de B comme paramtre dentre dune mthode de A
(strotype <<create>>) ;
V lutilisation par A dune mthode statique de B (strotype <<call>>) ;
V l instanciation dune classe gnrique B avec dfinition complte des types des paramtres pour crer une
classe B (strotype <<bind>>) ;
V la dclaration de A comme amie de B (strotype <<permit>>) ;
V
<<strotype>>

ClasseDependante

ClasseUtilisee

Figure D.27 : reprsentation UML dune dpendance

Implmentation relative au type de dpendance (<<strotype>>), au contexte, etc.

D.5.1 Dpendance du type <<instanciate>>


ClasseA

<<instanciate>>

ClasseB

Figure D.28 : reprsentation UML dune dpendance du type <<instanciate>>

Implmentation :
Dans lune des mthodes de la classe dpendante (ClasseA), dclaration, le plus souvent en dynamique, +
instanciation (<<instanciate>>) dun objet de la classe instancie (ClasseB), l o il est ncessit (.cpp), et pas en
tant quattribut.
Fichier ClasseA.h :

Fichier ClasseB.h :

class ClasseA
{
public:
void UneMethodeA();
};

class ClasseB
{
...
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
#include "ClasseB.h"

#include "ClasseB.h"
...

void ClasseA::UneMethodeA()
{
ClasseB* unB;
unB = new ClasseB();
...
delete unB;
}

D.5.2 Dpendance du type <<create>>


ClasseA

<<create>>

ClasseB

Figure D.29 : reprsentation UML dune dpendance du type <<create>>

Implmentation :
Pour lune des mthodes de la classe dpendante (ClasseA), dclaration en dynamique dun paramtre
(entre/sortie) du type de la classe utilise (ClasseB) et utilisation (<<create>>) de la rfrence sur ce paramtre
(.cpp).

95 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Fichier ClasseA.h :

Fichier ClasseB.h :

#include "ClasseB.h"

class ClasseB
{
public:
void UneMethodeB();
};

class ClasseA
{
public:
void UneMethodeA(ClasseB*);
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"

#include "ClasseB.h"

void ClasseA::UneMethodeA(ClasseB* b)
{
b->UneMethodeB();
...
}

void ClasseB::UneMethodeB()
{
...
}

D.5.3 Dpendance du type <<call>>


ClasseA

<<call>>

ClasseB

Figure D.30 : reprsentation UML dune dpendance du type <<call>>

Implmentation :
Pour la classe dpendante (ClasseA), appel (<<call>>) dune mthode statique de la classe utilise (ClasseB)
(.cpp).
Fichier ClasseA.h :

Fichier ClasseB.h :

class ClasseA
{
public:
void UneMethodeA();
};

class ClasseB
{
public:
static void UneMethodeB();
};

Fichier ClasseA.cpp :

Fichier ClasseB.cpp :

#include "ClasseA.h"
#include "ClasseB.h"

#include "ClasseB.h"
void ClasseB::UneMethodeB()
{
...
}

void ClasseA::UneMethodeA()
{
...
ClasseB::UneMethodeB();
...
}

D.5.4 Dpendance du type <<bind>>


ClasseA

<<bind>>

ClasseB

Figure D.31 : reprsentation UML dune dpendance du type <<bind>>

Implmentation :
La classe paramtre (ClasseA), est lie (<<bind>>) la classe gnrique (ClasseB) par instanciation du modle
avec des paramtres dfinis.

96 / 104

Programmation Oriente Objet > Langage C++ > Cours

Fichier ClasseA.h :
#include "ClasseB.h"
typedef ClasseB<int> ClasseA;

v1.5.4.2 27/05/2010

Fichier ClasseB.h :
template <class T>
class ClasseB
{
...
};

Fichier ClasseB.cpp :
#include "ClasseB.h"
...

97 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

E RFRENCE
E.1 PROGRAMMATION ORIENTE OBJET
E.1.1 Gnralits
Le terme objet dsigne une entit informatique spcifique, qui est une reprsentation abstraite simplifie dun objet
concret et abstrait du monde rel ou virtuel. Un objet appartient une famille dobjets et possde des variables
associes et des fonctions associes ; en terminologie objet, on parle respectivement de classe (famille dobjets),
attributs 1 (variables) et mthodes (fonctions).
Lorsque lon fait rfrence une classe, le terme de membres dsigne les attributs et les mthodes de cette classe.
La programmation oriente objet (POO) peut tre dfinie par les trois grands principes suivants :
V lencapsulation ;
V lhritage de classe ;
V le polymorphisme.

E.1.2 Principes
E.1.2.1

Lencapsulation

Lencapsulation consiste prserver la valeur des attributs de lobjet ; ceux-ci ne sont accessibles de lextrieur de
la classe que par lintermdiaire des mthodes de la classe. Les attributs sont dits alors privs (accs direct restreint
la classe seulement) ou protgs (accs direct restreint la classe et aux ventuelles sous-classes), alors que les
mthodes sont gnralement publiques 2 (accs possible lintrieur et lextrieur de la classe).

E.1.2.2

Lhritage de classe

Lhritage de classe permet de crer une nouvelle classe partir dune classe dj existante. Cela permet ainsi de
prciser, ou mettre jour une classe.
Du fait de lhritage, la nouvelle classe possde automatiquement des membres copis sur ceux de la classe dj
existante 3, lesquels peuvent tre complts par de nouveaux attributs et nouvelles mthodes. Dans le cadre de cet
hritage, la classe dj existante est appele la super-classe ou classe de base, et la nouvelle classe est appele la sousclasse ou classe drive / classe hrite.

E.1.2.3

Le polymorphisme

Le polymorphisme 4 est caractris par la dfinition de plusieurs mthodes homonymes, mais dont le comportement
et/ou la signature 5 diffrent, ou bien qui sappliquent des types dobjets distincts.
Il existe plusieurs types de polymorphismes :
V polymorphisme ad hoc : 2 classes diffrentes possdent chacune une mthode homonyme (nom et signature
identiques) mais dont le comportement est diffrent (adapt chaque classe) ; gnralement appel
surcharge 6 ;
1
2
3
4
5
6

Parfois appeles aussi proprits dans certains langages.


Une mthode peut cependant tre prive si elle est destine tre appele uniquement par dautres mthodes de la classe.
Uniquement si ceux-ci ont t dclars publics ou protgs.
Mot dtymologie grecque signifiant peut prendre plusieurs formes .
La signature dune mthode correspond au nombre et au type darguments (paramtres dentre) de la mthode.
Surcharge (fr) Z overloading (eng).
98 / 104

Programmation Oriente Objet > Langage C++ > Cours

V polymorphisme dhritage : 1 sous-classe hrite dune mthode

v1.5.4.2 27/05/2010
1

de la super-classe (nom et signature de la


mthode identiques), mais dont le comportement est diffrent (adapt la sous-classe par redfinition de la
mthode) ; aussi appel spcialisation 2. Ce type de polymorphisme est mis en uvre lors de lutilisation des
proprits de la gnralisation dans une hirarchie de classes.
V polymorphisme paramtrique : 1 classe possde plusieurs dfinitions dune mthode homonyme mais dont la
signature est diffrente ; aussi appel gnricit 3.
Par simplification, on parle souvent de surcharge pour nimporte quel type de polymorphisme.

E.2 EXCUTION ET RESSOURCES


Lun des rles du systme dexploitation est la gestion des ressources, et notamment de la mmoire vive disponible
physiquement sur une machine. En effet, celle-ci est commune on parle de mmoire centrale , et est partage entre
le systme dexploitation 4 et lensemble des programmes en cours dexcution.
Pour dvelopper efficacement il est donc extrmement important de se proccuper de lutilisation mmoire des
programmes crs, soit donc de la manire dont les diffrentes allocations ncessaires sont ralises.
Il sagit donc de dvelopper en optimisant lutilisation de mmoire vive selon deux axes :
V allouer un programme la mmoire ncessaire pour sexcuter de manire correcte ;
V minimiser la consommation de mmoire dun programme en librant celle-ci une fois utilise.

E.2.1 Allocation de mmoire


Dans un souci doptimisation, trois stratgies dallocation diffrentes existent, chacune correspondant une partie
appele segment de la mmoire alloue par le systme dexploitation un programme :
V allocation statique, segment text ;
5
V allocation sur la pile, segment stack ;
6
V allocation dans le tas, segment heap .
Pour chaque cas dutilisation de mmoire (stockage dune information, traitement dune procdure, cration dun
objet, etc.), lune des stratgies dallocation est donc utilise. Si certaines utilisations suivent une stratgie prdfinie,
dautres sont laisses au choix du programmeur.

E.2.1.1

Allocation statique

Lallocation statique consiste prvoir lespace mmoire ncessaire ds la phase de dveloppement ; il est alors
rserv avant lexcution du programme, dans le segment text, lorsque le celui-ci se charge en mmoire, juste avant
dtre excut.
Lors de lexcution, aucune modification nest apporte cette allocation ; lespace mmoire est libr la
terminaison du programme.
Lallocation statique offre ainsi un gain certain au niveau des performances, puisqu lexcution la mmoire est
immdiatement disponible.
Cependant, elle monopolise une partie de la mmoire centrale pendant toute la dure de lexcution, et ce mme si
un espace mmoire est trs peu voire pas utilis par le programme.
Les variables et instances globales, les dclarations externes, ainsi que les membres statiques suivent une allocation
statique.

E.2.1.2

Allocation sur la pile

Lallocation sur la pile consiste allouer/dsallouer automatiquement de la mmoire un programme au fur et


mesure des besoins en utilisant le segment stack, dont le stockage des informations est organis selon un principe de
pile de type LIFO 7.
1
2

3
4
5
6
7

Parmi un ensemble dautres membres.


Dans le cas dune mthode virtuelle spcialisation (fr) Z overriding (eng), et dans le cas dune mthode non-virtuelle
redfinition (fr) Z redefinition (eng).
Gnricit (fr) Z overloading (eng).
Le systme dexploitation nest rien dautre quune suite de logiciels coopratifs dont le rle est dexploiter la machine physique.
Stack (eng) Z pile (fr).
Heap (eng) Z tas (fr).
Last In First Out (eng) Z Dernier Arriv Premier Sorti (fr).
99 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Chaque besoin en mmoire devant utiliser la pile rserve un espace mmoire dans ce segment. Cet espace est
positionn dans la zone libre du segment, situe sur le dessus de la pile, juste aprs les prcdents espaces mmoire
antrieurement rservs, partir du premier espace mmoire libre ; on dit quil est empil.
Lorsque lespace mmoire nest plus ncessit, il peut tre libr. Seul lespace mmoire situ sur le dessus de la
pile peut tre libr ; on dit quil est dpil. Un espace mmoire situ sous un autre ne peut en aucune manire tre
libr ; il faut attendre que toutes les rservations postrieures soient libres.
Les besoins en mmoire sont donc gnralement allous et librs en suivant le fil dexcution dcrit dans le code
source, les uns la suite des autres, suivant les adresses dcroissantes.
Lespace mmoire tant allou/libr de manire automatique au cours de lexcution, on peut parler dallocation
dynamique pour les allocations utilisant la pile.
Ex. : Des allocations dynamiques sur la pile.
void procedureA()
{
char a;
}
int main(void)
{
char x;
procedureA();
char y;
return 0;
}
temps
adresses croissantes

sommet
de la pile
procedureA( )

main( )

main( )

a
x

main( )

y
x

Figure E.1 : exemple dallocations dynamiques sur la pile

En ralit, lors de la phase de compilation, il est facile de prvoir toutes les allocations sur la pile qui seront ralises
lors de lexcution ainsi que leur position relative. Dans un souci doptimisation, une allocation peut se voir rserver
un espace mmoire situ plus haut sur la pile quau niveau du sommet, laissant ainsi des espaces libres, car le
compilateur sait quils seront ncessaires au cours de lexcution.
Lallocation sur la pile peut donc tre aussi appele allocation statique sur la pile, en comparaison avec lallocation
dynamique dans le tas, et par rapprochement avec lallocation statique dans le segment text.
Ex. : Des allocations statiques sur la pile.
temps
adresses croissantes

sommet
de la pile
procedureA( )

main( )

main( )

main( )

y
x

Figure E.2 : exemple dallocations statiques sur la pile


100 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Lallocation sur la pile offre dexcellentes performances, puisquil est trs facile de retrouver le sommet de la pile, et
que les besoins en mmoire sont valus et grs en cours dexcution ; de plus, elle assure labsence de fuite de
mmoire 1 puisque les librations sont ralises automatiquement.
Par contre, il est ncessaire de connatre lavance la taille exacte de la rservation ncessite, information qui peut
voluer ou qui nest parfois connue que durant lexcution 2 ; en ce cas, lallocation sur la pile est donc inadquate.
Les appels de fonctions et de mthodes sont toujours grs suivant une allocation sur la pile 3. Les variables et
instances locales, dfinies dans la porte dune procdure, sont aussi alloues sur la pile ; par extension, il en est de
mme pour toutes les dfinitions locales un bloc de code. On peut aussi les appeler variables et instances lexicales,
car elles sont spcifiques la procdure, ou variables et instances automatiques 4 puisque lespace mmoire ncessaire
est allou la dclaration et libr automatiquement la fin de la procdure.

E.2.1.3

Allocation dans le tas

Lallocation dans le tas consiste allouer/dsallouer explicitement de la mmoire un programme lorsque cela est
ncessaire en utilisant le segment heap, qui ne suit aucune organisation ou logique particulire.
Chaque besoin en mmoire destin utiliser le tas ncessite la rservation dun espace mmoire dans ce segment,
rservation qui doit figurer explicitement dans le code source 5, et qui est donc du ressort du dveloppeur. Cet espace
est positionn dans toute zone libre du segment suffisamment grande pour accueillir la rservation ncessite,
gnralement la premire partir du dbut du tas.
Lorsque lespace mmoire nest plus ncessit, il peut tre libr. Cette libration doit aussi figurer explicitement
dans le code source 6 7.
Ex. : Des allocations dynamiques dans le tas.
int main(void)
{
char* x = new char;
char* y = new char;
char* z = new char;
delete y;
char* t = new char[2];
char* u = new char;
delete x, z, u;
delete[] t;
return 0;
}
temps
adresses croissantes

x
y
z

z
t[0]
t[1]

x
u
z
t[0]
t[1]

Figure E.3 : exemple dallocations dynamiques dans le tas

Lallocation dans le tas est dynamique, et offre donc de bonnes performances, condition de librer chaque espace
mmoire lorsquil nest plus utilis. Cest de plus une solution extrmement souple qui peut sadapter aux desiderata
du programmeur.
Nanmoins, cette souplesse a pour contre-partie de demander une grande rigueur, car lallocation et la libration
sont sous la responsabilit du programmeur. Tout espace mmoire allou, mme inutilis, reste rserv jusqu
1
2

3
4
5
6
7

Fuite de mmoire (fr) Z memory leak (eng).


Cest ce qui explique quil faut toujours spcifier la taille dun tableau lors dune dclaration statique dun tableau (type
tableau[taille];).
cf. E.2.2.
Avant la normalisation ANSI, le modificateur auto tait ncessaire pour dclarer une variable ou instance locale (cf. A.2.6).
Oprateur new.
Oprateur delete.
Certains langages, comme Java et C#, sont dots dun processus dit de ramasse-miettes (garbage collector (eng)) dont le rle est de librer
automatiquement les espaces mmoires allous dans le tas qui ne sont plus ncessits. Le dveloppeur na donc plus sen soucier.
101 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

libration explicite ou la terminaison du programme, et pas la fin de la procdure ; les risques de fuite de mmoire
sont donc rels, surtout si le programme sexcute sur une longue dure. De plus, une allocation dans le tas est trs
coteuse en ressources, puisquil faut parcourir le tas la recherche dune zone de mmoire libre dune capacit
suffisante. Enfin, lors dun grand nombre dallocation/dsallocation, le tas subit un phnomne de fragmentation
prjudiciable aux performances.
Toutes les dclarations dynamiques, ralises laide des pointeurs et de new/delete, sont alloues dans le tas.

E.2.2 Appel de procdure


Lors de lexcution dun programme, chaque procdure 1 dun programme occupe un segment de la mmoire
alloue pour le programme qui est indpendant des autres.
Chaque procdure se voit allouer de la mmoire dynamiquement sur la pile lors de son appel en suivant le fil
dexcution du code source. La mmoire ncessite par une procdure est empile sur le dessus de la pile, et est
libre lorsque la procdure se termine. Lorsquune procdure A appelle une autre procdure B, la procdure A est
donc empile, puis la procdure B est empile sur la A puisque celle-ci nest pas termine ; lorsque la procdure B est
termine, elle est dpile, laissant alors champ libre la procdure A pour se terminer son tour et enfin tre dpile.
Ex. : Une suite dappels de procdures allous sur la pile.
void procedureB()
{
...
}
void procedureC()
{
...
}
void procedureA()
{
procedureB();
procedureC();
}
int main(void)
{
procedureA();
return 0;
}
temps
adresses croissantes

main( )

procedureA( )
main( )

procedureB( )
procedureA( )
main( )

procedureC( )
procedureA( )
main( )

procedureA( )
main( )

main( )

Figure E.4 : appels de procdures allous sur la pile

Lorsque lon passe des paramtres dentre une procdure, les valeurs sont values puis recopies sur la pile, dans
le sens inverse de la liste darguments. Lespace mmoire ncessaire la rcupration de la valeur renvoye dans la
procdure appelante est rserv sur la pile la suite des valeurs des paramtres dentre, avant mme que la procdure
soit excute.
la terminaison de la procdure, le paramtre de linstruction return est valu puis recopi dans cet espace
mmoire ; ainsi toutes les allocations sur la pile ralises lintrieur de la procdure peuvent tre dpiles.
Ensuite, aprs avoir t utilis, il est dpil ; enfin, cest au tour des paramtres dentre dtre dpils.
1

Fonction ou mthode.
102 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

Ex. : Passage de paramtres dentre et rcupration de la valeur renvoye lors de lappel dune procdure.
int procedureA(int p1, int p2)
{
int a=3;
return a;
}
int main(void)
{
int x=1, y=2, z;
z = procedureA(x, y);
return 0;
}
temps
adresses croissantes

sommet
de la pile

procedureA( )

main( )

z
y (2)
x (1)

main( )

a (3)
return (3)
p1 (1)
p2 (2)
z
y (2)
x (1)

main( )

z (3)
y (2)
x (1)

Figure E.5 : passage de paramtres dentre et rcupration de la valeur renvoye lors de lappel dune procdure

103 / 104

Programmation Oriente Objet > Langage C++ > Cours

v1.5.4.2 27/05/2010

F BIBLIOGRAPHIE
Garreta Henri, Le langage C++, Universit de la Mditerrane Facult des sciences de Luminy, 2005 ;
Infini-software.com, Le langage C++ ANSI,
http://www.infini-software.com/Encyclopedie/Developpement/C_Cpp/CppAnsi/French/Index.wp, 2005 ;
Bodeveix Jean-Paul, Filali Mamoun, Sayah Amal, Programmation en C++, InterEditions, 1994 ;
Dancel Alain, Langage C++, http://membres.lycos.fr/dancel/, ENAC, 1999 ;
Groupe Steria, C++, Institut Aquitain dInformatique, 1994 ;
Garcia Bruno Ours blanc des CarpathesTM ,
Le C++ pour les pros et La librairie standard du C++, ISIMA, 1999 ;
CPlusPlus.com, C++ library reference, http://www.cplusplus.com/reference, 2008 ;
Guganno Claude, Programmation (II) Langage C++, http://claude.gueganno.free.fr/, 2004 ;
Casteyde Christian, Cours de C/C++ 1.40.6, http://casteyde.christian.free.fr/, 2002 ;
Eckel Bruce, Penser en C++ vol. 1 (Thinking in C++), http://bruce-eckel.developpez.com/, 2008 ;
Hardware.fr, Forum C/C++, http://forum.hardware.fr/hfr/Programmation/C++/liste_sujet-1.htm, 2006 ;
Hrauville Stphane, Cours Langage C++, CFAI Marcel Sembat Sotteville-ls-Rouen, 2002 ;
Muller Pierre-Alain, Gaertner Nathalie, Modlisation objet avec UML, Eyrolles, 2000 ;
Dcoret Xavier, Tutoriel STL, http://artis.imag.fr/~Xavier.Decoret/, ARTIS INRIA Rhne-Alpes, 2000 ;
CommentaMarche.net, C++, http://www.commentcamarche.net/cpp/, 2006 ;
Dveloppez.com, Langage C++, http://c.developpez.com/, 2006 ;
Roques Pascal, UML par la pratique, Eyrolles, 2003 ;
Bichon Jean, Cours de Systme dInformation Approche objet,
Licence informatique UFR Mathmatiques et Informatique Universit Bordeaux 1, 2004 ;
Lachaud Jacques-Olivier, Programmation C++ TD et TP, http://www.lama.univ-savoie.fr/wiki/,
Laboratoire de Mathmatiques UFR SFA Universit Savoie, 2000 ;
Wikipedia lencyclopdie libre, Allocation de mmoire et Call stack,
http://fr.wikipedia.org/ et http://en.wikipedia.org/, 2009 ;
Chang Chain-I, Assembly Language Programming C funtion call conventions and the stack,
http://www.cs.umbc.edu/~chang/cs313.s02/assembly.shtml,
CSEE Computer Science Electrical Engineering University of Maryland Baltimore County, 2001 ;
Seleborg Carl, Cours C++, http://carl.seleborg.free.fr/cpp/, 2001 ;
MediaDICO, http://www.mediadico.com, 2006 ;
Wikiversit communaut pdagogique libre, Langage C++, http://fr.wikiversity.org/, 2009 ;
Peignot Christophe, Langage C et Langage UML, http://info.arqendra.net/, 2009.

104 / 104