Académique Documents
Professionnel Documents
Culture Documents
en C++
Chapitre 1 : Notions de base
Auteur : A. MOHAMMEDI
Les classes en C++
08/12/19 INSIM TO 2
Les classes
L'en-tête : mot clé class suivi du nom de la classe.
Le corps : mis entre accolade, il est constitué des différentes
données et méthodes membres de la classe.
Une définition de classe est terminée par un point-virgule ou
par une liste de déclaration.
Exemple : l'en-tête de la classe
class personne
{
corps de la classe
string nom;
string prenom;
...}
;
08/12/19 INSIM TO 3
Les données membres d'une classe
08/12/19 INSIM TO 5
Les fonctions membres d'une classe
08/12/19 INSIM TO 7
Les fonctions membres d'une classe
Exemple :
Implémentation des fonctions getNom() et
getPrenom() à l'extérieur de la classe se fait
comme suit :
//utilisation de l'opérateur :: pour accéder au nom de la
fonction
string personne::getNom(){ return nom;}
string personne::getPrenom()
{return Prenom;}
08/12/19 INSIM TO 8
Objets de classe (instanciation simple)
08/12/19 INSIM TO 10
Accès à un membre de classe
08/12/19 INSIM TO 11
Masquage d'information
08/12/19 INSIM TO 12
Les classes et fonctions amies
But : autoriser des fonctions à accéder à des membres
non publics.
Une déclaration de classe amie commence par le mot-
clé friend.
Il ne peut apparaître que dans une définition de classe.
Les champs amis ne sont pas membres de la classe
donnant son amitié
il ne sont pas affectés par les sections public, private, et
protected dans lesquelles ils sont déclarés à l'intérieur du
corps de la classe.
08/12/19 INSIM TO 13
Les classes et fonctions amies
Un membre ami peut-être une fonction
d'espace de noms, une fonction membres d'une
autre classe, ou une classe complète.
Toutes les fonctions membres de la classe
amie peuvent accéder aux membres non
publics de la classe donnant son amitié.
Classe B Possibilité
Classe A Relation d’amitié d’accès
friend class A;
Membres de la
classe A Membres privés
et protégés de
la classe B
08/12/19 INSIM TO 14
Les classes et fonctions amies
Exemple :
La fonction non membre affiche() qui permet d'afficher les informations
relatives à un objet de la classe personne :
void affiche (const personne & p)
{
!
cout << "Le nom : \t" << p.nom << endl;
cout << "Age :\t" << p.age << endl;
}
Solution :
– Définir la fonction affiche() comme amie de la classe personne, comme
suit :
class personne {
friend void affiche (const personne &);
...//suite du corps de la classe
};
08/12/19 INSIM TO 15
Déclaration versus définition de classe
Déclaration : introduit le nom de la classe dans
le programme et indique que ce nom se réfère
à un type classe :
class nom_classe;
08/12/19 INSIM TO 17
Déclaration versus définition de classe
08/12/19 INSIM TO 18
Fonctions membres en ligne (inline)
08/12/19 INSIM TO 21
Les fonctions membres const
08/12/19 INSIM TO 22
Les fonctions membres const
Exemple :
class personne {
public :
string getNom () const;
int getAge() const {return age;}
...};
//définition de la fonction const getNom() à
l'extérieur de la classe
String personne::getNom()const
{return nom;}
08/12/19 INSIM TO 23
Le pointeur implicite this
08/12/19 INSIM TO 27
Le constructeur par défaut
Il peut ne pas être défini explicitement à condition
qu’aucun autre constructeur ne soit défini dans la
classe
Le constructeur par défaut d'une classe porte le même
nom que sa classe, et ne spécifie aucun argument
– Syntaxe :
nom_classe();
08/12/19 INSIM TO 29
Le constructeur de copie
L'initialisation d'un objet de classe avec un autre objet
de sa classe s'appelle initialisation membre à membre
par défaut.
Le concepteur de la classe peut fournir un
constructeur de copie de classe explicite.
– Syntaxe :
nom_classe(const nom_classe & rhs);
Il est invoqué chaque fois qu'un objet de classe est
initialisé avec un autre objet de sa classe.
Il est nécessaire de le définir lorsque qu'on a dans la
classe des données membres de type pointeur.
08/12/19 INSIM TO 30
Exemples de constructeurs
Exemple : Soit la classe personne suivante :
class personne {
public :
string nom;
string prenom;
Le constructeur par défaut
int age;
personne () { }
personne (string str_n, string str_p, int i)
{
nom = str_n;
prenom = str_p; Le constructeur avec
age = i; arguments
}
};
08/12/19 INSIM TO 31
Exemples de constructeurs
Exemple : On peut redéfinir le constructeur par défaut et le
constructeur avec arguments à l'aide de listes d'initialisation
comme suit :
class personne { Le constructeur par
public : défaut avec des valeurs
string nom; initiales pour chaque
donnée membre Le constructeur avec
string prenom; arguments plus
int age; efficace
personne (): nom ("x"), prenom ("y"), age (18)
{}
personne (string str_n, string str_p, int i) :
nom (str_n), prenom (str_p), age (i) {}
};
08/12/19 INSIM TO 32
Exemples de constructeurs
Exemple :constructeur de copie
class personne {
public :
…
personne (const personne &rhs)
{ if (&rhs != this)
{
nom = rhs.nom;
prenom = rhs.prenom
age = rhs.age;
}
}
};
08/12/19 INSIM TO 33
Exemples de construction
08/12/19 INSIM TO 34
Affectation d'objets de classe
L'affectation d'un objet de classe par un autre objet de sa classe
est gérée par l'affectation membre à membre par défaut.
Création implicite pour chaque classe de l'opérateur
d'affectation de copie.
Pour la classe personne précédente, l'opérateur ressemble à ce
qui suit :
inline personne& operator= (const personne &rhs)
{
nom = rhs.nom;
age = rhs.age;
return *this;
}
08/12/19 INSIM TO 35
Affectation d'objets de classe
08/12/19 INSIM TO 37
Destruction d'objets de classe
08/12/19 INSIM TO 38
Programmation orientée objet
en C++
Chapitre 2 : Héritage & polymorphisme
Auteur : N. TAMANI
L’héritage entre classes
08/12/19 INSIM TO 41
Différents types d'héritage
L'héritage de sous-type : c’est l’implémentation de la
relation "est un" ("est sorte de") entre classe.
– C'est une généralisation/spécialisation des classes à travers
un mécanisme de dérivation de classes.
– Exemple : un étudiant est une personne;
Une classe dérivée hérite des données et fonctions
membres de sa classe de base et peut les utiliser
comme si elles étaient membres de la classe dérivée
Si les classes de bases et dérivées partagent la même
interface publique, la classe dérivée et dite sous-type
de la classe de base.
08/12/19 INSIM TO 42
L’héritage en C++
L’héritage simple
L’héritage multiple
L’héritage virtuel
L’héritage abstrait
Le polymorphisme : corollaire à l’héritage
La composition
08/12/19 INSIM TO 43
Implémentation de l'héritage en C++
La syntaxe générale pour spécifier l’héritage entre classes est :
class derived : liste_de_dérivation
{
//... définition de la classe dérivée
};
derived : c'est le nom de la classe dérivée;
liste_de_dérivation : c'est une liste formée de
access_specificator base_class séparés par des virgules;
base_class : est le nom de la classe de base;
Les classes spécifiées dans la liste de dérivation doivent être définies
avant d'être utilisées comme des classes de base;
08/12/19 INSIM TO 44
Implémentation de l'héritage en C++
access_specificator : un modificateur qui peut
être :
– public : d'où l'héritage public (héritage de sous-
type);
– protected : d'où l'héritage protégé;
– private : d'où l'héritage privé.
Le spécificateur indique la propagation de
l’héritage en termes de droits d'accès aux
données et fonctions membres de la classe de
base dans la classe dérivée :
08/12/19 INSIM TO 45
Implémentation de l'héritage en C++
08/12/19 INSIM TO 46
L’héritage simple (unique)
Un héritage simple est une dérivation de classe
dans laquelle chaque classe dérive (sous classe)
d'une seule et unique classe de base (super
classe).
Personne
Les membres communs Membres de la
aux classes étudiant et classe personne
enseignant sont mis dans
la classe personne
Étudiant Enseignant
Membres de la Membres de la
classe étudiant classe enseignant
08/12/19 INSIM TO 47
L’héritage simple (unique)
08/12/19 INSIM TO 48
Construction des objets dans l'héritage simple
La règle générale :
– Instancier un objet de la classe dérivée déclenche
un processus d'appel au constructeur de la classe
de base, puis enfin le constructeur de la classe
dérivée concernée.
Chaque objet de la classe dérivée possède un
sous objet de sa classe de base.
08/12/19 INSIM TO 49
Construction des objets dans l'héritage simple
1.Création du sous
objet personne
Personne
Personne
Étudiant
2. Création de l’objet
étudiant
08/12/19 INSIM TO 50
Instanciation par défaut
08/12/19 INSIM TO 52
Instanciation avec arguments
Exemple :
class personne {
public :
//...
personne (string n, string p, int a) :
nom (n), prenom (p), age (a) {}
Appel explicite du
//...};
constructeur avec
class etudiant : public personne {arguments de la classe
public : personne
int anne_etud;
etudiant (string ne, string pe, int ae, int
anne) :
personne (ne, pe, ae),
anne_etud (an) { }
//...};
08/12/19 INSIM TO 53
Accès aux membres de la classe de base
08/12/19 INSIM TO 54
Accès aux membres de la classe de base
08/12/19 INSIM TO 55
Destruction des objets dans l’héritage
08/12/19 INSIM TO 56
Destruction des objets dans l’héritage
1. Destruction de l’objet
étudiant
Personne
Personne
Étudiant
Étudiant
2. Destruction du sous
objet personne
08/12/19 INSIM TO 57
Le polymorphisme
08/12/19 INSIM TO 58
Le polymorphisme
08/12/19 INSIM TO 59
Conséquence du Polymorphisme
08/12/19 INSIM TO 60
Conséquence du Polymorphisme
Exemple : la fonction se_deplacer() dans les classes
personne et étudiant :
class personne {
public :
void se_deplacer () {//à pied}
//...};
class etudiant : public personne {
public :
void se_deplacer () {//par bus}
//...};
Quelle est la fonction à invoquer dans :
p->se_deplacer();
?
08/12/19 INSIM TO 61
Conséquence du Polymorphisme
Solutions :
1. La solution par défaut
2. Les fonctions virtuelles
La solution par défaut : le compilateur résout
le conflit en imposant que la fonction
appelée soit celle définie dans le type du
pointeur (ou référence);
– Dans notre cas : c'est personne::se_deplacer()
qui sera invoquée;
08/12/19 INSIM TO 62
Le Polymorphisme et les fonctions virtuelles
08/12/19 INSIM TO 63
Le Polymorphisme et les fonctions virtuelles
08/12/19 INSIM TO 64
Le Polymorphisme et les fonctions virtuelles
La classe dérivée peut :
– soit fournir sa propre version de la fonction, qui devient
l'instance active pour cette classe;
– soit hériter de la version de la classe de base.
Le mécanisme de fonctions virtuelles ne fonctionne
correctement qu'avec les pointeurs et références.
Le mécanisme virtuel ne permet pas d'appeler une
fonction membre de la classe dérivée non définie
dans sa classe de base
Les données membres de la classe dérivée ne sont pas
accessibles via un pointeur ou référence vers la classe
de base
08/12/19 INSIM TO 65
Le polymorphisme et les destructeurs
Soit le pointeur p :
personne *p = new etudiant;
p est un pointeur de la classe de base pointant un
objet de la classe dérivée.
L’instruction : delete (p);
!
le destructeur de la classe personne qui sera appelé
pour détruire un objet etudiant;
Donc, il est plus que nécessaire de définir aussi le
destructeur de la classe de base comme étant virtuel.
08/12/19 INSIM TO 66
Le polymorphisme et les destructeurs
08/12/19 INSIM TO 67
Héritage multiple
08/12/19 INSIM TO 68
Héritage multiple
Exemple : Un amphibien est à la fois un
animal aquatique et terrestre :
Terrestre Aquatique
Membres de la Membres de la
classe terrestre classe aquatique
Amphibien
Membres de la
classe amphibien
08/12/19 INSIM TO 69
Héritage multiple
L'implémentation de la classe Amphibien :
class Amphibien : public Aquatique, public
Terrestre
{//... Les membres de classe Amphibien
};
Une classe de base ne peut apparaître dans une liste
d'héritage multiple que si sa définition a déjà été
fournie
Pas de limitation du nombre de classes de base qui
peuvent apparaître dans une liste de dérivation
La classe dérivée contient un sous objet de chacune
de ses classes de base.
08/12/19 INSIM TO 70
Invocation des constructeurs et destructeurs
Le processus de création d'un objet d'une classe qui
dérive de plusieurs classes de base est similaire au
processus vu pour l'héritage simple.
Invocation de tous les constructeurs des classes de
base dans le même ordre de leurs déclarations dans la
liste de dérivation.
1.Création du sous
objet Aquatique
08/12/19 INSIM TO 71
Invocation des constructeurs et destructeurs
L'ordre d'application des destructeurs est
toujours l'inverse de l'ordre d'invocation des
constructeurs.
Exemple :
3. Destruction du sous
objet Aquatique
08/12/19 INSIM TO 72
Membres hérités de plusieurs classes
08/12/19 INSIM TO 73
Les fonctions virtuelles et l'héritage multiple
Les déclarations/définitions virtuelles sont possibles
dans l'héritage multiple.
Le traitement est identique à celui de l'héritage
simple.
Lorsqu'un objet de la classe dérivée est alloué via un
pointeur sur un objet de l'une de ses classes de base,
alors les parties spécifiques aux autres classes de base
dans l'objet dérivé ne sont plus accessibles.
08/12/19 INSIM TO 74
Conséquence de l’héritage multiple
Exemple : Les classes aquatique et terrestre dérivent
toutes les deux de la classe animal :
Animal
Membres de la
classe animal
Terrestre Aquatique
Membres de la Membres de la
classe terrestre classe aquatique
Amphibien
Membres de la
classe amphibien
08/12/19 INSIM TO 75
Conséquence de l’héritage multiple
08/12/19 INSIM TO 76
L’héritage virtuel
Résolution du problème :
– Si le comportement obtenu par cette forme d'héritage est
celui désiré utilisation des noms qualifiés pour les accès;
– Sinon utilisation du mécanisme de l'héritage virtuel.
Définition : dans l'héritage virtuel un seul sous objet
partagé de la classe de base racine est hérité, quel que
soit le nombre d'apparition de la classe de base dans la
hiérarchie de dérivation.
La classe de base partagée est dite classe de base
virtuelle
08/12/19 INSIM TO 77
L’héritage virtuel
Pour qu'une classe devienne une classe de base virtuelle, il
suffit de faire précéder son nom, dans la liste de dérivation, du
mot clé virtual
Exemple : Implémentation de l'héritage virtuel ci-dessus :
class animal L'ordre des mots clés public
et virtual n'est pas important
{//...};
class aquatique : public virtual animal
{//...};
class terrestre : virtual public animal
{//...};
class amphibien : public aquatique, public
terrestre
{//...};
08/12/19 INSIM TO 78
Appel des constructeurs dans d'héritage virtuel
08/12/19 INSIM TO 79
Constructeurs/destructeurs dans d'héritage
virtuel
08/12/19 INSIM TO 80
Fonctions virtuelles pures et classes abstraites
Une fonction virtuelle pure est une fonction virtuelle
dont le prototype (signature) est suivi d'une
affectation à 0 [lippman];
La classe qui déclare ce type de fonctions devient
automatiquement une classe abstraite;
La redéfinition des fonctions virtuelles pures est
obligatoire dans toutes les classes dérivées à partir de
cette classe de base abstraite; Dans le cas contraire,
ces classes dérivées deviennent aussi des classes
abstraites.
08/12/19 INSIM TO 81
Fonctions virtuelles pures et classes abstraites
08/12/19 INSIM TO 82
Fonctions virtuelles pures et classes abstraites
08/12/19 INSIM TO 84
La composition par valeur
08/12/19 INSIM TO 85
La composition par valeur
08/12/19 INSIM TO 86
La composition par référence
08/12/19 INSIM TO 87
Programmation orientée objet
en C++
Chapitre 3 : La programmation générique
Auteur : N. TAMANI
La programmation générique
La généricité est un mécanisme de programmation
qui permet d’implémenter des modules (fonctions ou
classe) indépendamment des types de données.
Le but du chapitre : prendre connaissance des bases
de la programmation génériques
Les modèles (patron ou template) de fonctions
Les modèles de classes.
Présentation de la STL (Standard Template Library).
08/12/19 INSIM TO 89
Les patrons de fonctions
08/12/19 INSIM TO 90
Les patrons de fonctions
Exemple : la fonction max()
– Elle peut s’appliquer de façon identique sur des valeurs
entières, doubles, de type string et même sur des objets de
classe surchargeant l'opérateur de test (généralement
l'opérateur supérieur à >).
– La fonction max() peut se définir comme étant un patron de
fonction.
int max (int a, int b)
{ if (a>b) return a; return b;}
T max (T a, T b)
double max (double a, double b) {
{ if (a>b) return a; return b;}
= if (a>b) return a;
return b;
string max (string a, string b) }
{ if (a>b) return a; return b;}
08/12/19 INSIM TO 91
Déclaration/définition d'un patron de fonctions
Syntaxe :
template <liste_param_type>
//declaration/definition du patron.
template : mot clé du langage pour introduire un modèle de
classe;
list_param_type : la liste des paramètres du patron de la
forme :
class ident ou typename ident séparées par des virgules, ou
encore type_real ident;
class et typename étant des mots clés du langage qui
introduisent ident comme étant un paramètre de type;
type_real un type simple ou composé prédéfini ou défini par
l'utilisateur qui introduit ident comme un paramètre de valeur
du patron;
08/12/19 INSIM TO 92
Déclaration/définition d'un patron de fonctions
Exemple : le patron de fonction max() déclaré comme suit :
template <typename T>
T max ( T, T);
– max() est un patron de fonction qui accepte deux arguments de type T
et retourne une valeur de type T;
La définition du patron de fonction max () :
template <typename T>
T max ( T a, T b)
{
if (a > b) return a;
return b;
}
Le programmeur peut paramétrer tous les types, ou un sous
ensemble des types, dans l'interface (type retour + signature)
du patron de fonctions
08/12/19 INSIM TO 93
Les paramètres d’un patron de fonctions
On peut avoir comme paramètre de patron un paramètre non
type; ce nom correspond alors à une valeur transmise au
patron de la fonction. • La référence pour tab est
Exemple : obligatoire
template <class T, int size> • size est la taille de tab;
void affiche (T (&tab) [size]);
Un identificateur utilisé pour spécifier un paramètre de patron
garde ce statut tout le long de la déclaration/définition du
patron :
Il cache toute déclaration/définition d'objet, classe, type, fonction, etc.
apparaissant dans les portées englobant la déclaration/définition du
patron de fonction.
Toute déclaration/définition d'objets, ou type à l'intérieur de la
définition d'un patron ne doit pas avoir un nom identique à l'un des
identificateurs utilisés pour spécifier un paramètre de ce patron
08/12/19 INSIM TO 94
Les paramètres d’un patron de fonctions
08/12/19 INSIM TO 95
Les paramètres d’un patron de fonctions
Les noms de paramètres de patron n'ont pas besoin
d'être identiques entre la déclaration et la définition
d’un même patron.
Pas de contrainte de nombres d'apparition d'un nom
de paramètre de patron dans la liste de paramètres de
la fonction;
Un patron de fonctions peut aussi être déclaré inline
ou extern;
le mot clé inline (ou extern) ne se mettra pas avant le mot clé
template mais il sera placé devant le type retour du patron :
Exemple :
template <class T>
inline T min (T, T);
08/12/19 INSIM TO 96
Instanciation de patron de fonctions
08/12/19 INSIM TO 97
Instanciation de patron de fonctions
08/12/19 INSIM TO 98
Arguments de patron explicites
Soit l'appel suivant :
x
long int li;
cout << max (li, 3) << endl;
Le processus de déduction d'arguments ne pourra pas
instancier une fonction max (long int, int)
Incapacité de trouver la fonction à appeler
spécification d'arguments explicites;
La syntaxe est comme suit :
nom_patron <liste_types_réels> (liste_argument_fonction);
liste_types_réels : liste de types réels séparés par des
virgules; chaque type dans cette liste correspond à un
paramètre de type du patron;
08/12/19 INSIM TO 99
Arguments de patron explicites
Exemple : Instancier le patron max() avec les
arguments li et 3 :
on doit passer par une fonction de spécification
explicite d'arguments :
max<long int> (li, 3);
Le compilateur instanciera directement la fonction
max(long int, long int); sans passer par la déduction
d'arguments.
Il n'est pas obligatoire de fournir pour chaque
paramètre de type un argument explicite dans la liste
d'arguments explicites;
Les arguments qui peuvent être déduits de façon
implicite ne nécessitent pas d'arguments explicites;
08/12/19 INSIM TO 100
Arguments de patron explicites
On respectera alors la même règle vue pour les arguments par
défaut pour une fonction :
on ne peut omettre que les arguments les plus à droite.
Il existe une autre situation où l'utilisation d'arguments de
patron explicites est inévitable :
template <class T1, class T2>
T1 fct (T2);
Lors de l'appel de la fonction avec un type donné, la déduction
d'argument n'a pas la possibilité de déduire le type réel à
affecter à T1;
on doit impérativement passer par les arguments de patron
explicite : Instancier la fonction :
fct <int> (3.14); int fct (double); puis l'invoquer
array <int, x> v;
Corriger cette erreur :
x
const int x = 20;
array <int, x> v;
Le compilateur l'adresse d'un objet membre d'espace
de noms ainsi que le résultat de l'expression sizeof()
sont des expressions constantes.