Académique Documents
Professionnel Documents
Culture Documents
Cours 2
Mohamed
El Nabil
Abdellaoui SaïdSaidi 2020 2021
Classe, Objet
2
Classe, Objet
Avantages :
rapproche les données et leur traitement: c'est l'objet qui sait le mieux comment gérer une
demande (lien sémantique )
Mohamed
El Nabil
Abdellaoui SaïdSaidi 3
Classe, Objet : Exemple
Exemple : Classe « Point » :
Point
- x : int aa ba c
- y : int
+ SetPoint() : void x =? x =? x =?
y=? y=? y=?
+ Deplacer() : void
+ Afficher() : void
Les attributs (données) x et y sont dites privées. Ceci signifie que l’on ne peut les manipuler qu’au
travers des fonctions membres (l’encapsulation des données).
SetPoint() Deplacer() Afficher(); ce sont les méthodes appliqués sur les objets de type Point. On
l’appelle aussi des fonctions membres.
a, b et c sont des objets de classe «Point», c’est-à-dire des variables de type «Point». On parle
aussi d ’instances.
Mohamed
El Nabil
Abdellaoui SaïdSaidi 4
Classe, Objet
Déclaration d’une classe
Syntaxe :
class NomClass{
//...
};
Exemple :
class Rectangle {
private : double h;
double L;
//...
};
h =?
L=?
Mohamed
El Nabil
Abdellaoui SaïdSaidi 5
Attributs
syntaxe
[ Modificateur ] : nomAttribut;
☞ Ce modificateur influence sur toute les lignes qui le suit jusqu’à la présence d’un autre,
Exemple
private : int a;
double b;
double périmétre () {
// coprs
}
public : double surface () {
// coprs
}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 6
Méthodes
La déclaration des méthodes suit deux façons :
Externe : : La déclaration des méthodes est à l’extérieure de la classe. Pour relier la définition d’une
méthode à sa classe, il suffit d’utiliser l’opérateur :: de résolution de portée.
Mohamed
El Nabil
Abdellaoui SaïdSaidi 7
Principe de programmation
L'encapsulation peut se pratiquer en donnant à l'utilisateur
un fichier en-tête contenant la déclaration de la classe;
un module objet contenant la version compilée du fichier contenant la définition de la classe.
Il s'agit de ne montrer à l'utilisateur que ce qui lui est destiné compilée du fichier contenant la définition de
la classe. Dans la version plus élaborée:
seules des fonction d'accès et de modification sont rendues publiques;
toute donnée est privée ou protégée;
Exemple : Pour assurer une bonne encapsulation, on décompose notre programme comme suit :
un fichier Point.h de déclaration de la classe Point
un fichier Point.cpp d'implémentation des méthodes de la classe
un fichier Demo_Point.cpp d'utilisation.
Point.h Point.cpp Demo_Point.cpp
#include <iostream>
ifndef POINT_H
#include "Point.cpp"
#define POINT_H #include "Point.h"
using namespace std;
class Point
void main() {
//Attribut et protopyes //Définitions de Méthodes
/* instanciation de
};
la classe */
#endif
}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 8
Exemple : Encapsulation (déclaration interne)
Point.cpp
#include <iostream>
using namespace std;
class Point {
private : int x, y;
public:
Void setPoint(int a,int b){x=a;y=b;}
};
void main() {
Point a, b;
a.setPoint(1, 2); b.setPoint(3,-5);
a.affiche(); // x = 1, y = 2
a.deplace(1,1);
a.affiche(); // x = 2, y = 3
}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 9
Exemple : Encapsulation (déclaration externe)
Point.cpp
#include <iostream>
using namespace std;
class Point {
private : int x, y;
public:
void setPoint (int, int);
void deplace (int, int);
void affiche();
};
void Point::setPoint(int a,int b){x=a;y=b;}
void main() {
Point a, b;
a.setPoint(1, 2); b.setPoint(3,-5);
a.affiche(); // x = 1, y = 2
a.deplace(1,1);
a.affiche(); // x = 2, y = 3
}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 10
Exemple : Encapsulation (Version améliorée)
#ifndef POINT_H
#define POINT_H
class Point {
private : int x, y;
Point.h
public:
void setPoint (int, int);
void deplace (int, int);
void affiche(); };
#endif
#include <iostream>
#include "Point.h"
Point.cpp
#include <iostream>
#include "Point.cpp"
Demo_Point.cpp
Mohamed
El Nabil
Abdellaoui SaïdSaidi 11
Constructeur & Destructeur
12
Notion de Constructeur
Le constructeur permet de d’ instancier une classe et initialiser les attributs.
Propriétés d’un constructeur :
porte toujours le même nom que la classe
ne renvoie pas de valeur de retour (même pas un void)
garantit que l ’objet sera toujours initialisé.
Syntaxe :
Exemple :
Si aucun constructeur n’est spécifié, le compilateur génère automatiquement une version minimale
du constructeur par défaut par défaut qui :
appelle le constructeur par défaut des attributs objets.
laisse non initialisés les attributs de type de base.
Dès qu’au moins un constructeur a été spécifié, ce constructeur par défaut par défaut n’est plus
fourni.
Si donc on spécifie un constructeur sans spécifier de constructeur par défaut, on ne peut plus
construire d’objet de cette classe sans les initialiser (ce qui est voulu !) puisqu’il n’y a plus de
constructeur par défaut.
On peut le rajouter si on veut :
NomClasse()= default;
Mohamed
El Nabil
Abdellaoui SaïdSaidi 14
Constructeur par défaut
Constructeur par défaut : est un constructeur sans arguments ou dont chacun des arguments possède une
valeur par défaut. Il est utilisé lorsque l’on crée des tableaux d’objets.
Exemple : class Toto {
private : int n;
public : Toto( int i); //constructeur}
};
void main(){
Toto tableau[3]; //Erreur : il faut un constructeur par défaut
getch() ;}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 15
Auto-référence : le pointeur this
Si, dans une méthode, un attribut est masqué alors la valeur de l’attribut peut quand même être
référencée à l’aide du mot réservé this.
this->nom_attribut
Exemple :
class point {
int x,y
public :
void initialise(int , int);
};
void point :: initialise(int x, int y)
{this->x=x; this->y=y}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 16
Notion de plusieurs constructeurs
#ifndef POINT_H
#define POINT_H
class Point {
Point.h
private : int x, y;
public: void setPoint (int, int);
void deplace (int, int);
void affiche(); };
#endif
#include <iostream.h>
#include "Point.h"
Point.cpp
Point::Point(){x=20;y=10;} // constructeur 1
Point::Point(int a,int b){x=a;y=b;} // constructeur 2
Point::Point(int a){x=a;y=30;} // constructeur 3
//affichage
//destructeur
#include <iostream>
#include "Point.h”
#include "Point.cpp"
Demo_Point.cpp
Mohamed
El Nabil
Abdellaoui SaïdSaidi 17
Notion de constructeur pour les pointeurs
#ifndef POINT_H
#define POINT_H
class Point {
Point.h
private : int x, y;
public: void setPoint (int, int);
void deplace (int, int);
void affiche(); };
#endif
#include <iostream.h>
#include "Point.h«
Point.cpp
//affichage
Point::Point(int x, int y){this->x=x;this->y=y;}
//destructeur
#include <iostream>
#include "Point.h”
Demo_Point.cpp #include "Point.cpp"
using namespace std;
main() {
point *p;
p=new point(10,4);
p->afficher();
}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 18
Notion de Destructeur
Le destructeurs permet de spécifier ce qui doit être fait quand l'objet est désalloué. Ceci est important
quand un constructeur fait de l'allocation explicite.
Syntaxe :
~ NomClasse() { //… }
class vecteur{
int taille,*v;
Exemple :
public:
//constructeur
vecteur( int n) {if (n>0) taille = n; v=new int[n];}
//destructeur
~ vecteur() {delete v; cout<< "appel au destructeur"}
};
Mohamed
El Nabil
Abdellaoui SaïdSaidi 19
Exemple : Constructeur
#ifndef POINT_H
#define POINT_H
class Point {
Point.h
private : int x, y;
public: Point (int, int);
void deplace (int, int);
void affiche (); };
#endif
#include <iostream>
#include "Point.h"
Point::Point(int a,int b):x(a),y(b){}
Point.cpp
#include <iostream>
Demo_Point.cpp
#include "Point.cpp"
using namespace std;
main() {
Point a(1, 2),b(3,-5);
a.affiche(); // x = 1, y = 2
a.deplace(1,1);
a.affiche(); // x = 2, y = 3 }
Mohamed
El Nabil
Abdellaoui SaïdSaidi 20
Méthodes (Action & Prédicat )
En C++, on peut distinguer les méthodes qui modifient l’état de l’objet (« actions ») de celles qui ne
changent rien à l’objet (« prédicats »). On peut pour cela ajouter le mot const après la liste des paramètres de
la méthode :
class Rectangle{
double hauteur;
double largeur;
double surface() const ; // prototype
};
// définition
double Rectangle :: surface() const
{
return hauteur×largeur;
}
Si vous déclarez une action en tant que prédicat (const), vous aurez à la compilation le message
d’erreur :
Mohamed
El Nabil
Abdellaoui SaïdSaidi 21
Accesseurs et manipulateurs
Afin d’assurer l’encapsulation; il est préférable d’utiliser le modificateur d’accès private.
Les membres privés ne sont accessibles que par les méthodes membres.
Mohamed
El Nabil
Abdellaoui SaïdSaidi 22
CONSTRUCTEUR
DE COPIE
23
CONSTRUCTEUR DE COPIE
=> r1 et r2 sont deux instances distinctes mais ayant des mêmes valeurs
pour leurs attributs.
Ceci pose typiquement problème lorsque certains attributs de la classe sont des pointeurs.
Examinons pourquoi sur un exemple concret...
Mohamed
El Nabil
Abdellaoui SaïdSaidi 24
CONSTRUCTEUR DE COPIE
Soit une autre définition possible de classe Rectangle :
class Rectangle {
private:
double *largeur,*hauteur; // aîe, un pointeur !
public:
Rectangle(double l, double h) : largeur(new double(l)), hauteur(new double(h))
{}
~Rectangle() { delete largeur; delete hauteur; }
void afficher_largeur () { cout << "Largeur: " << * largeur<< endl; }
double getLargeur() const;
double getHauteur() const; // …
};
Mohamed
El Nabil
Abdellaoui SaïdSaidi 25
EXEMPLE
Avant
r1
la copie Largeur
Hauteur
Après
r1 r2
la copie Largeur
Hauteur
Après la
destruction r1 r2
de tmp Largeur
Hauteur
☞ Il faut redéfinir le constructeur de copie de sorte à ce qu’il duplique véritablement les champs concernés → copie
profonde
Mohamed
El Nabil
Abdellaoui SaïdSaidi 26
CONSTRUCTEUR DE COPIE
Solution :
class Rectangle {
private:
double *largeur,*hauteur; // aîe, un pointeur !
public:
Rectangle(double l, double h) : largeur(new double(l)), hauteur(new double(h))
{}
~Rectangle() { delete largeur; delete hauteur; }
void afficher_largeur () { cout << "Largeur: " << * largeur<< endl; }
double getLargeur() const;
double getHauteur() const; // …
};
Mohamed
El Nabil
Abdellaoui SaïdSaidi 27
EXEMPLE
Mohamed
El Nabil
Abdellaoui SaïdSaidi 28
EXEMPLE
Lorsque afficher_largeur a fini de s’exécuter, l’objet tmp est automatiquement détruit par le
destructeur de la classe Rectangle
Le destructeur va libérer la mémoire pointée par les champs largeur et hauteur de tmp.
☞ Attention ! cette portion de mémoire est aussi utilisée par r dans un appel comme
afficher_largeur(r) !
☞ Gros risque de segmentation Faut lors de la prochaine utilisation de r !!
Mohamed
El Nabil
Abdellaoui SaïdSaidi 29
EXEMPLE
Avant
r tmp
la copie Largeur
Hauteur
Après
r tmp
la copie Largeur
Hauteur
Après la
destruction r tmp
de tmp Largeur
Hauteur
☞ Il faut redéfinir le constructeur de copie de sorte à ce qu’il duplique véritablement les champs concernés → copie
profonde
Mohamed
El Nabil
Abdellaoui SaïdSaidi 30
SOLUTION
Avant
r tmp
la copie Largeur
Hauteur
Après la
destruction r tmp
de tmp Largeur Largeur
Hauteur Hauteur
Mohamed
El Nabil
Abdellaoui SaïdSaidi 31
EXEMPLE : DÉFINITION COMPLÈTE DE LA CLASSE
class Rectangle {
public:
Rectangle(double l, double h) : largeur(new double(l)), hauteur(new double(h)) {}
Rectangle(const Rectangle& );
~Rectangle();
// Note: il faudrait aussi redefinir operator= !
private: double *largeur, *hauteur;
};
// constructeur de copie
Rectangle:: Rectangle(const Rectangle& obj) : largeur(new double(*(obj.largeur))),
hauteur(new double(*(obj.hauteur)))
{ }
// destructeur
Rectangle::˜Rectangle() {delete largeur; delete hauteur;
}
Mohamed
El Nabil
Abdellaoui SaïdSaidi 32
POUR CONCLURE
Exemple :
Rectangle( Rectangle const& autre)
:hauteur(autre.hauteur), largeur(autre.largeur)
{}
Par ailleurs, si l’on souhaite interdire la copie, il suffit de supprimer le constructeur de copie par défaut
avec la commande « = delete » vue dans la séquence précédente.
class PasCopiable{
/* ... */
PasCopiable (PasCopiable const&) = delete;
};
Mohamed
El Nabil
Abdellaoui SaïdSaidi 33
LES CONSTRUCTEURS EN C++ (RÉSUMÉ)
Méthode constructeur(initialisation des attributs) :
NomClass(liste arguments) :
attribut1(...),
attributN(...)
{
// autres opérations
}
~NomClasse() {
// opérations de libération
}
Des versions par défaut (minimales) de ces méthodes sont générées automatiquement par C++ si on ne
les fournit pas
Règle : si on en définit une explicitement, il faut toutes les redéfinir !
Mohamed
El Nabil
Abdellaoui SaïdSaidi 34
LES TECHNIQUES
DE
L’HÉRITAGE
35
INTRODUCTION
Figure
Polygone Ellipse
Mohamed
El Nabil
Abdellaoui SaïdSaidi 36
PRINCIPES DE L’HÉRITAGE
Le concept de l ’héritage constitue l’un des fondements de la P.O.O. Il a pour objectif de hiérarchiser
les classes et les objets.
Il consiste à définir une nouvelle classe, appelée classe dérivée (ou classe Fille), à partir d ’une classe
existante appelée classe de base (classe mère).
La classe dérivée hérite des potentialités de la classe de base, tout en lui en ajoutant de nouvelles.
Mohamed
El Nabil
Abdellaoui SaïdSaidi 37
PRINCIPES DE L’HÉRITAGE
Une classe dérivée contient
Attributs :
les attributs de sa classe de base; Class de base
Méthodes :
possède a priori les méthodes de sa classe de base Class dérivée
C++ autorise l ’héritage multiple dans lequel une classe peut être dérivée de plusieurs classes de base.
Mohamed
El Nabil
Abdellaoui SaïdSaidi 38
ACCÈS AUX MEMBRES
Récapitulatif des changements de niveaux d’accès aux membres hérités, en fonction du niveau
initial et du type d’héritage :
Accès initial
public Protected private
public public Protected Pas d’accès
Héritage
Mohamed
El Nabil
Abdellaoui SaïdSaidi 39
ACCÈS PROTÉGÉ
Le niveau d’accès protégé correspond à une extension du niveau privé aux membres des sous-classes.
Le niveau d’accès protégé correspond à une extension du niveau privé permettant l’accès aux sous-
classes… mais uniquement dans leur portée (de sous-classe), et non pas dans la portée de la super-classe
Exemple 1 :
Mohamed
El Nabil
Abdellaoui SaïdSaidi 40
ACCÈS PROTÉGÉ
Le niveau d’accès protégé correspond à une extension du niveau privé aux membres des sous-classes.
Le niveau d’accès protégé correspond à une extension du niveau privé permettant l’accès aux sous-
classes… mais uniquement dans leur portée (de sous-classe), et non pas dans la portée de la super-classe
Exemple 2 :
Mohamed
El Nabil
Abdellaoui SaïdSaidi 41
ACCÈS PROTÉGÉ
Le niveau d’accès protégé correspond à une extension du niveau privé aux membres des sous-classes.
Le niveau d’accès protégé correspond à une extension du niveau privé permettant l’accès aux sous-
classes… mais uniquement dans leur portée (de sous-classe), et non pas dans la portée de la super-classe
Exemple 3 :
Mohamed
El Nabil
Abdellaoui SaïdSaidi 42
MASQUAGE & APPEL D’UNE MÉTHODE DE LA SUPER-CLASSE
Exemple 2 :
Appel de la fonction }
de protected:
la class mère
char couleur; };
Mohamed
El Nabil
Abdellaoui SaïdSaidi 43
COMPOSITION OU HÉRITAGE
Une classe est composée si certains de ses membres sont eux-mêmes des objets.
La description d'un habitant fait partie d'une carte d'identité;
correct car une carte d'identité n'est pas un cas particulier d'un habitant
La description d'un résident est plus complète que celle d'un habitant: l'information supplémentaire est
l'adresse de sa résidence (qui peut être différente de celle de son domicile).
l’héritage doit être utilisé pour décrire une relation « est-un » ("is-a")
Attention
il ne doit jamais décrire une relation « a-un »/« possède-un » ("has-a" ) Composition
Mohamed
El Nabil
Abdellaoui SaïdSaidi 44
EXEMPLES
Exemple :
Une voiture possède quatre (ou cinq) roues, donc
class Automobile {
Roue roues[5]; //…};
class segment {
Point p1,p2; //Point points[2];
//… };
Mohamed
El Nabil
Abdellaoui SaïdSaidi 45
CONSTRUCTEURS & HÉRITAGE
46
CONSTRUCTEURS PAR DÉFAUT & HÉRITAGE
DescrResidence::DescrResidence() {
// appel implicite du constructeur par défaut de la classe de base.
cout << "Entrez votre residence : " ; cin >> residence; }
void DescrResidence::show() {
DescrHabitant::show() ; // l'appel de la méthode de la classe de base.
cout << "Residence \t" << residence << endl ; }
Mohamed
El Nabil
Abdellaoui SaïdSaidi 47
CONSTRUCTEURS PAR DÉFAUT & HÉRITAGE
Mohamed
El Nabil
Abdellaoui SaïdSaidi 48
CONSTRUCTEURS & HÉRITAGE
Lorsque la super-classe admet un constructeur par défaut, l’invocation explicite de ce constructeur dans la
sous-classe n’est pas obligatoire
☞ le compilateur se charge de réaliser l’invocation du constructeur par défaut
Mohamed
El Nabil
Abdellaoui SaïdSaidi 49
CONSTRUCTEURS & HÉRITAGE
Exemple :
class Rectangle {
protected: double largeur; double hauteur;
public: Class Rectangle
Rectangle(double l, double h) : largeur(l), hauteur(h){} largeur
// le reste de la classe... hauteur
};
Mohamed
El Nabil
Abdellaoui SaïdSaidi 50
CONSTRUCTEURS & HÉRITAGE
Autre exemple (qui ne fait pas la même chose) :
class Rectangle {
protected: double largeur; double hauteur;
public:
Rectangle() : largeur(0.0), hauteur(0.0){}
// constructeur par défaut
// le reste de la classe...
};
Ici il n’est pas nécessaire d’invoquer explicitement le constructeur de la classe parente puisque celle-ci
admet un constructeur par défaut.
Mohamed
El Nabil
Abdellaoui SaïdSaidi 51
HÉRITAGE & CONSTRUCTEUR DE COPIE
Exemple :
Mohamed
El Nabil
Abdellaoui SaïdSaidi 52
HÉRITAGE & CONSTRUCTEURS
Les constructeurs ne sont, en général, pas hérités
Mais en C++11 on peut demander leur héritage en utilisant le mot clé « using » . On récupère alors
tous les constructeurs de la super-classe, i.e. on peut construire la sous-classe avec les mêmes arguments,
mais...
☞ Attention ! ces constructeurs n’initialisent donc pas les attributs spécifiques de la sous-classe.
☞ C’est donc très risqué, et je vous conseille de ne l’utiliser que pour des sous-classes n’ayant pas de
nouvel attribut (et si c’est approprié) !
Mohamed
El Nabil
Abdellaoui SaïdSaidi 53
HÉRITAGE (RÉCUP)
Spécifier un lien d’héritage :
SuperClasse::membre
Le constructeur d’une sous classe doit faire appel au constructeur de la super classe :
Mohamed
El Nabil
Abdellaoui SaïdSaidi 54