SlideShare une entreprise Scribd logo
1  sur  52
L’héritage en C++
Ecole Marocaine des Sciences de l’Ingénieur
Marrakech
Héritage simple
Plan du chapitre
▪ Présentation de concept de l’héritage simple
▪ Mise en œuvre de l’héritage
▪ Utilisation dans une classe dérivée des membres de la classe de base
▪ Redéfinition des fonctions membres
▪ Appel des constructeurs et des destructeurs
▪ Contrôle d’accès
▪ Conversion d’un objet dans un objet d’un type de base
Présentation de concept de l’héritage simple
▪ Qu’est ce que l’héritage ?
▪ L’héritage consiste, à partir d’une classe existante A, à définir une nouvelle classe B.
▪ La classe existante A est appelée classe mère, ou classe de base.
▪ La nouvelle classe B est appelée classe fille ou dérivée de la classe A.
▪ On dit que la classe B dérive ou hérite de la classe A.
▪ Une classe fille hérite automatiquement des données et méthodes de sa classe mère sans
avoir à les réécrire.
▪ Une classe mère peut avoir plusieurs classe filles.
▪ Une classe fille peut elle même servir de classe mère pour une autre classe fille.
▪ On parle de l’héritage simple, quand une classe fille hérite d’une seule classe mère.
Présentation de concept de l’héritage simple
▪ Exemple
Classe
véhicule
Classe
DeuxRoues
Classe Vélo Classe Moto
Classe
QuatreRoues
Classe
Camion
Classe voiture
Présentation de concept de l’héritage simple
▪ Utilité de l’héritage
▪ L’héritage permet de réutiliser des classes existantes
▪ L’héritage permet d’adapter des classes existantes à ses propres besoins
▪ L’héritage permet de faire évoluer les classes sans avoir à les réécrire de A à Z.
▪ L’héritage permet de moduler les classes et de les spécialiser au fur et à
mesure des besoins.
▪ L’héritage permet d’éviter de construire des classes de taille trop importante.
Mise en œuvre de l’héritage
▪ La définition d’une classe dérivée d’une classe de base se fait de la manière suivante
(héritage simple):
class nom classe dérivée : modificateur accès nom classe de base
{
Déclaration des membres (données et méthodes) de la classes dérivée
Définitions des méthodes de la classe dérivée
}
Mise en œuvre de l’héritage
Exemple simple sans constructeur ni destructeur
class point{
private:
int x, y;
public:
void initialise(int a, int b){ x=a; y=b; }
void deplace(int a, int b){ x=x+a; y=y+b; }
void affiche(){
cout<<"Point : "<<x<<" - "<<y<<endl;
}
};
class point_colore:public point{
int couleur;
public:
void colorer(int c) { couleur=c; }
};
Hérite de
main(){
point_colore p; // p de type point_colore
p.initialise(12,27); //méthode de la classe point
p.colorer(7);
p.affiche(); //méthode de la classe point
p.deplace(1,2); // méthode de la classe point
p.affiche(); // méthode de la classe point
}
- La déclaration ‘class point_colore : public point’
spécifie que la classe 'point_colore' est dérivée de
la classe de base 'point'.
- Le mot clé ‘public’ signifie que les membres
publics de la classe de base seront des membres
public de la classe dérivée.
Utilisation dans une classe dérivée des membres de la classe
de base
▪ Après avoir fait appel à la fonction ‘ colorer ’, la fonction ‘affiche’ ne donne aucune information sur la
couleur d'un point.
▪ Ce qui nous conduit donc a créer une fonction ‘ affiche_c ’ membre de ‘point_colore’ pour afficher les
coordonnées x, y et la couleur c.
▪ Or, une classe dérivée n'a pas accès aux membres privés de la classe de base. La solution est donc
:
void affiche_c(){
cout<<"Point : "<<x<<" - "<<y<<endl;
cout<<"En couleur : "<<couleur<<endl;
}
void affiche_c() {
affiche(); //solution accéder à x et y via la méthode affiche qui est public
cout<<" en couleur : "<<couleur<<endl;
}
Utilisation dans une classe dérivée des membres de la classe
de base
▪ De même on peut initialiser x, y et couleur en même temps avec une fonction ‘ initialise_c ’ de la classe
dérivée 'point_colore'.
▪ Le programme de la classe point_c complet est donc :
class point_colore:public point{
int couleur;
public:
void colorer(int c) { couleur=c; }
void affiche_c(){
affiche();
cout<<"en couleur : "<<couleur<<endl;
}
void initialise_c(int a, int b, int c){
initialise(a,b);
couleur= c;
}
};
int main(){
point_colore p;
p.initialise_c(12,27,9);
p.colorer(7);
p.affiche();
p.affiche_c();
p.deplace(1,2);
p.affiche();
p.affiche_c();
}
Redéfinition des fonctions membres
▪ Les méthodes 'affiche' de la classe 'point' et 'affiche_c‘ de la classe 'point_colore' font un travail
analogue. De même pour les fonctions 'initialise' et 'initialise_c'.
▪ En c++, il est possible de redéfinir la fonction 'affiche‘ ou la fonction 'inialise’ pour la classe dérivée.
▪ Exemple
class point_colore:public point {
int couleur;
public:
void colorer(int c) { couleur=c; }
void affiche(){
point::affiche();
cout<<"en couleur : "<<couleur<<endl;
}
void initialise(int a, int b, int c) {
point::initialise(a,b);
couleur= c;
}
};
int main(){
point_colore p;
p.affiche();
p.initialise(12, 27, 9);
p.affiche();
p.point::affiche();
p.deplace(10, 20);
p.affiche();
p.colorer(7);
p.affiche();
}
Contrôle d’accès
2 . les membres protégés d’une classe
▪ Les membres protégés restent inaccessibles à l’utilisateur (comme les membres privés). Mais ils seront
accessibles aux membres d'une éventuelle classe dérivée, tout en restant inaccessibles aux utilisateurs
de cette classe.
▪ Exemple : supposons qu’on a
▪ On peut donc déclarer dans la classe 'point_colore‘ dérivée de la classe 'point' une fonction 'affiche' qui
accède aux membres protégés x et y.
class point{
protected:
int x, y;
public:
void initialise(int, int);
void deplace(int, int);
void affiche();
};
Héritage offre plusieurs avantages
▪ Cela évite d'avoir à réécrire le même code à plusieurs reprises. Un ancêtre peut
transmettre des propriétés à tous ses descendants.
▪ En termes de codage, cela peut vous faire économiser beaucoup de temps et de
travail.
▪ Cela réduit le nombre d'endroits où des bogues pourraient être introduits dans le
programme, ainsi vous réduisez le temps de débogage.
▪ Il permet le polymorphisme
En pratique, l'héritage fonctionne de plusieurs
manières
▪ D'un point de vue descendant, l'héritage orienté objet peut être considéré
comme un moyen de prendre une idée plus générale et de la diviser en idées
plus spécialisées.
▪ Mais l'héritage peut également fonctionner d'un point de vue ascendant, où
vous commencez avec la progéniture et décidez quel type d'ancêtre ils ont en
commun. Que ce soit descendant ou ascendant, le résultat final est un
arrangement similaire de classes.
Contrôle d'accès et héritage
▪ Une classe dérivée peut accéder à tous les membres non privés de sa classe de
base.
▪ Les membres de la classe de base qui ne devraient pas être accessibles aux
fonctions membres des classes dérivées doivent être déclarés privés dans la
classe de base.
▪ Selon le modificateur d'accès utilisé pendant l'héritage, la disponibilité des
membres de la classe Super class dans la sous-classe change. Il peut être
soit private, protected ou public.
Héritage public
▪ Lors de la dérivation public d'une sous-classe d'une classe de base, les
membres publiques de la classe de base deviennent des membres publiques
de la classe dérivée et les membres protégés de la classe de base
deviennent des membres protégés de la classe dérivée.
▪ Les membres privés d'une classe de base ne sont jamais accessibles
directement à partir d'une classe dérivée, mais sont accessibles via des
appels aux membres publiques et protégés de la classe de base.
#include <iostream>
using namespace std;
class Base {
private:
int pvt ;
protected:
int prot ;
public:
int pub ;
Base(){pvt=1; prot=2;pub=3;}
// function to access private member
int getPVT() {
return pvt;
}
};
class PublicDerived : public Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access public member from Base
int getPub() {
return pub;
}
};
int main() {
PublicDerived object1;
//cout << "Private cannot be accessed." << endl;
cout << "Private = " << object1.getPVT() << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Exemple: Discussion selon le mode de dérivation: accès direct à un champ
#include <iostream>
using namespace std;
class Base {
public:
int pub ;
public:
Base(){pub=3;}};
class PublicDerived : protected Base {
public:
int getPub() {
return pub;
}
};
int main() {
PublicDerived object1;
object1.pub;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Héritage protected
▪ Lors de la dérivation protected d'une sous-classe d'une classe de base, les
membres publiques et protégés de la classe de base deviennent des
membres protégés de la classe dérivée.
Exemple
#include <iostream>
using namespace std;
class Base {
private:
int pvt ;
protected:
int prot ;
public:
int pub ;
Base(){pvt=1; prot=2;pub=3;}
// function to access private member
int getPVT() {
return pvt;
}
};
class ProtectedDerived : protected Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access public member from Base
int getPub() {
return pub;
}
};
int main() {
ProtectedDerived object1;
cout << "Private cannot be accessed." << endl;
//cout << "Private = " << object1.getPVT() << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Lorsque vous utilisez l'héritage protégé, les membres publics et protégés de
la classe de base deviennent des membres protégés de la classe dérivée.
Cela signifie que les membres publics de la classe de base deviennent
accessibles en tant que membres protégés dans la classe dérivée.
Dans votre code, getPVT() est une fonction membre de la classe Base
qui accède à la variable privée pvt.
Étant donné que ProtectedDerived hérite de Base en mode
protégé, même les membres privés de Base deviennent des membres
protégés de ProtectedDerived
et ne sont donc pas accessibles directement en dehors de la classe dérivée.
Héritage private
▪ Lors de la dérivation private d'une sous-classe d'une classe de base, les
membres publiques et protégés de la classe de base deviennent des
membres privés de la classe dérivée.
▪ Syntaxe:
#include <iostream>
using namespace std;
class Base {
private:
int pvt ;
protected:
int prot ;
public:
int pub ;
Base(){pvt=1; prot=2;pub=3;}
// function to access private member
int getPVT() {
return pvt;
}
};
class PrivateDerived : private Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access public member from Base
int getPub() {
return pub;
}
};
int main() {
PrivateDerived object1;
cout << "Private cannot be accessed." << endl;
//cout << "Private = " << object1.getPVT() << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Porquoi l’héritage privé
▪ L'objectif principal de cet héritage est de créer une relation "est implémenté en termes de" plutôt
qu'une relation "est un type de" (comme c'est le cas avec l'héritage public).
▪ Quelques points clés concernant l'héritage privé :
▪ Restreindre l'accès : Les membres publics et protégés de la classe de base deviennent privés dans
la classe dérivée. Cela signifie que ces membres ne sont pas accessibles en dehors de la classe
dérivée.
▪ Implémentation de comportement : L'héritage privé est souvent utilisé pour réutiliser
l'implémentation d'une classe de base dans une classe dérivée sans exposer l'interface de la classe
de base.
▪ Sécurité et encapsulation : Cela renforce l'encapsulation en limitant l'accès aux membres de la
classe de base, empêchant ainsi les modifications involontaires de la classe dérivée par des
utilisateurs extérieurs.
▪ Sous-classe spécialisée : L'héritage privé peut être utile pour créer des sous-classes spécialisées
qui utilisent l'implémentation de la classe de base, mais qui ne doivent pas être utilisées directement
en dehors de la classe dérivée.
▪ L'héritage protégé en programmation orientée objet offre un niveau d'encapsulation intermédiaire
entre l'héritage public et l'héritage privé. Lorsque vous utilisez l'héritage protégé, les membres publics
de la classe de base deviennent des membres protégés dans la classe dérivée, tandis que les
membres protégés de la classe de base restent protégés dans la classe dérivée.
▪ Quelques raisons d'utiliser l'héritage protégé :
▪ Encapsulation contrôlée : L'héritage protégé permet de contrôler l'accès aux membres de la classe
de base. Les membres publics de la classe de base deviennent accessibles uniquement à la classe
dérivée et à ses classes dérivées ultérieures, ce qui renforce l'encapsulation tout en permettant une
certaine extension.
▪ Relation "est implémenté en termes de" : Comme avec l'héritage privé, l'héritage protégé est
souvent utilisé pour définir une relation "est implémenté en termes de". Cela signifie que la classe
dérivée implémente certaines fonctionnalités en utilisant des éléments de la classe de base sans
exposer directement l'interface de la classe de base.
▪ Réutilisation du code : L'héritage protégé permet à la classe dérivée d'utiliser et de réutiliser les
fonctionnalités et le comportement de la classe de base tout en limitant l'accès aux parties sensibles
ou critiques de cette classe.
▪ Spécialisation contrôlée : Il permet de créer des classes dérivées spécialisées qui peuvent étendre
et modifier le comportement des classes de base sans que ces modifications ne soient directement
visibles à l'extérieur.
▪ Souplesse dans la conception : L'héritage protégé offre une certaine souplesse dans la conception
des classes, permettant de créer des hiérarchies de classes bien structurées et modifiables avec un
niveau de contrôle supplémentaire.
Contrôle d’accès
1 . L’héritage privé
▪ Pour que l’utilisateur d’une classe dérivée n’ait pas accès aux membres publics de sa classe de base, il
suffit de remplacer le mot ‘public’ par ‘private’ dans sa déclaration.
▪ Exemple
▪ Si on a :‘point_colore O(12, 4, 6) ;’ les appels suivants sont rejetés : ‘O.affiche() ;’ ou ‘O.point::affiche();’
‘O.deplace(1,5);’ ou ‘O.point::depace(1,5);’
▪ Cette technique de fermeture d’accès à la classe de base ne sera employée que dans des cas précis,
lorsque par exemple toutes les fonctions utiles de la classe de base sont redéfinies dans la classe
dérivée, et qu’il n’y a aucune raison de laisser l’utilisateur accéder aux anciennes.
class point{
int x, y;
public:
void initialise (inta,int b) { x=a; y=b; }
void deplace (inta,intb) { x=x+a; y=y+b;}
void affiche() { ……………………… }
};
class point_colore:private point {
int couleur;
public:
void colorer(int c) { couleur=c; }
};
Autre Exemple
d’héritage simple
#include <iostream>
using namespace std;
//Classe de base
class Vehicule
{
public:
int id_vh;
string marque;
int vitesse;
};
// Sous-classe héritant de la classe de base (véhicule)
class Voiture : public Vehicule
{
public:
int id_vt;
};
//fonction main
int main()
{
Voiture v;
// L'objet de la classe enfant a tous les membres de données
v.id_vh = 3;
v.id_vt = 58;
v.marque = "Land";
v.vitesse = 300;
cout << "ID de Voiture est : " << v.id_vh << endl;
cout << "ID de Vehicule est : " << v.id_vt << endl;
cout << "La marque : " << v.marque << endl;
cout << "La vitesse : " << v.vitesse << endl;
return 0;
}
Contrôle d’accè
Contrôle d’accès
3 . Tableau récapitulatif sur l’héritage et les modificateurs d’accées
Classe de base Modificateur d’accès Classe dérivées
public public public
public private private
protected public protected
protected private private
private public non accessible
private private non accessible
Appel des constructeurs et des destructeurs
▪ Exemple
▪ Si on a :
class point{
int x, y;
public:
point(int, int) ;
…………………………….
…………………………
} ;
class point_colore:public point{
int couleur;
public:
point_colore(int, int, int) ;
………………………….
………………………..
} ;
Appel des constructeurs et des destructeurs
#include <iostream>
using namespace std;
class Base
{
int a;
public:
Base() : a(0) {cout<<"construction objet classe de base"<<" "<<"a="<<a<<endl;}
Base(int A) : a(A) {cout<<"construction objet classe de base"<<" "<<"a="<<a<<endl;}
~Base(){cout<<"destruction partie classe de base"<<" a="<<a<<endl;}
};
class Derived : public Base{
int b;
public:
Derived(): b(0) {cout<<"construction objet classe Derivee"<<" "<<"b="<<b<<endl;} // appel implicite à Base()
Derived(int i, int j) : Base(i), b(j) {cout<<"construction objet classe Derivee"<<" "<<"b="<<b<<endl;} // appel explicite
~Derived(){cout<<"destruction partie classe derivee"<<" b="<<b<<endl;}
};
int main() {
Derived D;
Derived DD(3,4);
return 0;
}
#include <iostream>
using namespace std;
//************Class point******
class point{
int x,y;
public:
point(int abs=0,int ord=0){
cout<<"++ Construct Point:"<<abs<<" "<<ord<<endl;
x=abs; y=ord;
}
~point(){
cout<<"-- Destr Point:"<<x<<" "<<y<<endl;
}
};
//************Class pointcol******
class pointcol: public point{
short couleur;
public:
pointcol(int abs=0,int ord=0, short c=1):point(abs,ord){
cout<<"++ Construct PointCol:"<<abs<<" "<<ord<<" "<<c<<endl;
couleur=c;
}
~pointcol(){
cout<<"-- Destr Couleur:"<<couleur<<endl;
}
};
int main() {
pointcol a(10,15,3);
pointcol b(2,3);
pointcol c(12);
pointcol * adr;
adr=new pointcol(12,25);
delete adr;
return 0;
}
Appel des constructeurs et des destructeurs
▪ Pour créer un objet de la classe ‘point_colore’, il faut tout d’abord créer un objet de la classe ‘point’,
donc faire appel au constructeur de la classe ‘point’, le compléter par ce qui est spécifique a la classe
‘point_colore’ et faire appel au constructeur de la classe ‘point_colore’.
▪ Si on souhaite que le constructeur de la classe ’point_colore’ retransmette au constructeur de la classe
‘point’ les premières informations reçues, on écrira :
▪ Ainsi, la déclaration : ‘point_colore(2, 4, 5) ;’ entraînera :
▪ l’appel du constructeur ’point’ qui recevra les valeurs 2 et 4.
▪ l’appel du constructeur ’point_colore’ qui recevra les valeurs 2, 4 et 5.
point_colore(int a, int b, int c):point(a, b)
Nom de la classe dérivée (paramètres):nom de la classe mère(paramètres)
Syntaxe :
Exemple :
Appel des constructeurs et des destructeurs
▪ Il est toujours possible de mentionner les valeurs par défaut :
▪ Donc la déclaration ‘point_colore(17) ;’ entraîne :
▪ appel du constructeur ‘point’ avec les valeurs 17 et 2.
▪ appel du constructeur ‘point_colore’ avec les valeurs 17 , 2 et 5.
point_colore(int a=0, int b=2, int c=5):point(a,b)
Appel des constructeurs et des destructeurs
1 . Exercice
Reprendre le programme précédent en ajoutant les constructeurs et les destructeurs
correspondants, tout en affichant les moments de construction et de destruction des objets.
Appel des constructeurs et des destructeurs
2 . D’une manière générale
▪ Si la classe de base ne possède pas de constructeur, aucun problème particulier ne se pose. De même
si elle ne possède pas de destructeur.
▪ En revanche, si la classe dérivée ne possède pas de constructeur, alors que la classe de base en
comporte, le problème sera posé lors de la transmission des informations attendues par le constructeur
de la classe de base. La seule situation acceptable est celle où la classe de base dispose d’un
constructeur sans arguments.
▪ Lors de la transmission d’informations au constructeur de la classe de base, on peut utiliser des
expressions ou des arguments.
▪ Exemple
pointcolore(int a=5, int b=5, int c=4):point(a*2, b*5);
Appel des constructeurs et des destructeurs
3 . Cas du constructeur de recopie
Compléter le programme précédent en ajoutant les constructeurs par recopie.
Conversion d'un objet dérivé dans un objet d'un type
de base
▪ Si on a :
▪ l'affectation ‘O1=O2 ;’ est juste.
▪ l'affectation ‘O2=O1 ;’ est rejetée (si O2 a des arguments définis par défaut, on aura pas de problème).
point O1;
point_colore O2;
Exercice
1. Créer une classe de base Article. Un article possède deux champs privés:
• Nom : string
• Prix : double
Et les opérations publiques :
• getPrix() : pour retourner le prix de l'article
• setPrix(double) : pour changer le prix de l'article
• afficher() : permet d’afficher le prix.
2. Réaliser ensuite une classe ArticleEnSolde, dérivée de la classe Article. Cette sous-classe
comprend une information additionnelle:
• remise : pourcentage de réduction sur le prix d'origine
• setRemise(entier) pour changer la remise.
La classe va redéfinir la méthode getPrix(), afin de tenir compte du solde.
Elle va également redéfinir la méthode afficher(), afin que l'affichage donne également le
pourcentage de remise sur le prix d'origine.
#include<iostream>
using namespace std;
class Article{
protected:
string nom;
double prix;
public:
Article():nom(""),prix(0){};
Article(string a,double b):nom(a),prix(b){};
double getPrix(){return prix;}
void setPrix(double a){prix=a;}
void afficher(){cout<<"le prix d article "<<nom<<" est : "<<prix<<endl; }
};
class ArticleEnSolde: public Article{
double remise;
public:
ArticleEnSolde():remise(0){};
ArticleEnSolde(string nom,double prix,double a):Article(nom,prix){
remise=a;
};
void setRemise(double a){remise=a;}
double getPrix(){return prix;}
double RemiseSurPrixOrigine(){return prix*remise/100;}
void afficher(){
double px=prix-prix*remise/100;
Article::afficher();cout<<"le prix d article apres remise est : "<<px<<endl;}
};
main(){
ArticleEnSolde B("chaise",100,20);
B.afficher();
}
Héritage multiple
Plan du chapitre
▪ Mise en œuvre de l’héritage multiple
▪ Les classes virtuelle
▪ Appel des constructeurs et des destructeurs dans le cas des classes virtuelles
Mise en œuvre de l’héritage multiple
▪ L’exemple suivant met en évidence la notion d’héritage multiple à travers la classe
‘point_colore’ héritant des classes ‘point’ et ‘coul’.
Mise en œuvre de l’héritage multiple
class point {
int x,y;
public:
point(int a, int b){
x=a ; y=b ;
cout<<’’Constructeur de point ’’ ;
}
~point() { cout<<’’Destructeur de point ’’ ; }
void affiche() {
cout<<’’point ’’ <<x<<’’-‘’<<y ;
} };
class coul {
int couleur ;
public :
coul(int c){
couleur=c ; cout<<’’Construction de coul ’’ ;
}
~coul() { cout<<’’Destruction de coul ’’ ; }
void affiche() { cout<<’’Couleur : ’’ <<couleur<<endl ; }
} ;
class point_colore:public point, public coul {
public:
point_colore (int a, int b, int c):point (a,b) , coul(c){
cout<<’’construction de pointcoloren’’ ;
}
~point_colore() { cout<<’’destruction de pointcoloren’’ ; }
void affiche() { point::affiche(); coul::affiche(); }
};
void main() {
point_colore o(100, 200, 3);
o.affiche();
}
Exemple
Les classes virtuelle
▪ Si on a :
▪ Donc les déclarations suivantes :
▪ Impliquent que la classe ‘D’ hérite deux fois de la classe ‘A’, donc les membres de ‘A’ vont
apparaître deux fois dans ‘D’.
▪ les fonctions membres ne sont pas réellement dupliquées.
▪ les données membres seront effectivement dupliquées.
class A {
int x, y ;
……………….
……………….
};
class B:public A {
………………
………………
};
class D:public B, public C {
………….
.…………
};
class C:public A {
………………
………………
};
Les classes virtuelle
▪ Solution
▪ si on ne veut pas de cette duplication, on précisera la classe ‘A’ comme classe virtuelle dans les
déclarations des classes ‘B’ et ‘C’.
class A {
int x, y ;
……………….
……………….
};
class B:public virtual A {
………………
……………… };
class D:public B, public C {
………….
.…………
};
class C:public virtual A
{
………………
……………… };
- le mot-clé ‘virtual’ apparaît dans la classe ‘B’ et la classe ‘C’.
- le mot-clé ‘virtual’ peut être placé avant ou après le mot-clé ‘public’.
Remarques :
▪ Si ‘A’ n’est pas déclarée ‘virtual’ dans les classes ‘B’ et ‘C’, les constructeurs seront
appelés dans l’ordre : ‘A1’, ‘B’, ‘A2’, ‘C’ et ‘D’.
▪ Si ‘A’ a été déclarée ‘virtual’ dans ‘B’ et ‘C’, on ne construira qu’un seul objet de type de ‘A’
(et non pas deux objets).
Quels arguments faut-il transmettre alors au constructeur ? Ceux prévus par ‘B’ ou ceux prévus par ‘C’ ?
Question :
Appel des constructeurs et des destructeurs dans le cas des
classes virtuelles
▪ Le choix des informations à transmettre au constructeur de ‘A’ se fait, non plus dans ‘B’ ou
‘C’, mais dans ‘D’. Pour ce faire, C++ autorise (uniquement dans ce cas) à spécifier, dans
le constructeur de ‘D’, des informations destinées à ‘A’.
▪ Ainsi, on peut avoir :
D(int a, int b, int c):B(a, b, c), A(a, b)
▪ Bien entendu, il sera inutile de préciser des informations pour ‘A’ au niveau des
constructeurs ‘B’ et ‘C’.
▪ En ce qui concerne l’ordre des appels, le constructeur d’une classe virtuelle est toujours
appelé avant les autres. Dans notre cas, on a l’ordre ‘A’, ‘B’, ‘C’ et ‘D’.
Appel des constructeurs et des destructeurs dans le cas des
classes virtuelles
▪ L’ordre des appels des constructeurs est : B, A, C, D et E.
Exemple :
Appel des constructeurs et des destructeurs dans le cas des
classes virtuelles

Contenu connexe

Similaire à Héritage dans cpp dev informatique ingenierie

Csharp2 : classes et objets
Csharp2 : classes et objetsCsharp2 : classes et objets
Csharp2 : classes et objetsAbdoulaye Dieng
 
Chapitre 2 classe et objet
Chapitre 2   classe et objetChapitre 2   classe et objet
Chapitre 2 classe et objetAmir Souissi
 
Ch4HeritageSMI2015_2016.pdf
Ch4HeritageSMI2015_2016.pdfCh4HeritageSMI2015_2016.pdf
Ch4HeritageSMI2015_2016.pdfRihabBENLAMINE
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfslimyaich3
 
PHP 5 pour les développeurs Java
PHP 5 pour les développeurs JavaPHP 5 pour les développeurs Java
PHP 5 pour les développeurs JavaMehdi EL KRARI
 
chapitre5-Classesabstraitesetinterfaces.pdf
chapitre5-Classesabstraitesetinterfaces.pdfchapitre5-Classesabstraitesetinterfaces.pdf
chapitre5-Classesabstraitesetinterfaces.pdfMoez Moezm
 
Formation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetFormation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetkemenaran
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonAbdoulaye Dieng
 
S2-02-PHP-objet.pptx
S2-02-PHP-objet.pptxS2-02-PHP-objet.pptx
S2-02-PHP-objet.pptxkohay75604
 
Fondamentaux java
Fondamentaux javaFondamentaux java
Fondamentaux javaInes Ouaz
 
Chapitre5: Classes et objets
Chapitre5: Classes et objetsChapitre5: Classes et objets
Chapitre5: Classes et objetsAziz Darouichi
 

Similaire à Héritage dans cpp dev informatique ingenierie (20)

POO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdfPOO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdf
 
Ch10
Ch10Ch10
Ch10
 
Csharp2 : classes et objets
Csharp2 : classes et objetsCsharp2 : classes et objets
Csharp2 : classes et objets
 
2006 2007-heritage-en-c++
2006 2007-heritage-en-c++2006 2007-heritage-en-c++
2006 2007-heritage-en-c++
 
Ch03
Ch03Ch03
Ch03
 
POO
POOPOO
POO
 
Langage C#
Langage C#Langage C#
Langage C#
 
Chapitre 2 classe et objet
Chapitre 2   classe et objetChapitre 2   classe et objet
Chapitre 2 classe et objet
 
Cours c++
Cours c++Cours c++
Cours c++
 
XB-Java.ppt
XB-Java.pptXB-Java.ppt
XB-Java.ppt
 
Ch4HeritageSMI2015_2016.pdf
Ch4HeritageSMI2015_2016.pdfCh4HeritageSMI2015_2016.pdf
Ch4HeritageSMI2015_2016.pdf
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdf
 
PHP 5 pour les développeurs Java
PHP 5 pour les développeurs JavaPHP 5 pour les développeurs Java
PHP 5 pour les développeurs Java
 
chapitre5-Classesabstraitesetinterfaces.pdf
chapitre5-Classesabstraitesetinterfaces.pdfchapitre5-Classesabstraitesetinterfaces.pdf
chapitre5-Classesabstraitesetinterfaces.pdf
 
Formation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetFormation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objet
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en Python
 
S2-02-PHP-objet.pptx
S2-02-PHP-objet.pptxS2-02-PHP-objet.pptx
S2-02-PHP-objet.pptx
 
Fondamentaux java
Fondamentaux javaFondamentaux java
Fondamentaux java
 
Chapitre5: Classes et objets
Chapitre5: Classes et objetsChapitre5: Classes et objets
Chapitre5: Classes et objets
 
Cpp3 : heritage
Cpp3 : heritageCpp3 : heritage
Cpp3 : heritage
 

Dernier

Câblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdfCâblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdfmia884611
 
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...Institut de l'Elevage - Idele
 
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdfJTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdfInstitut de l'Elevage - Idele
 
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...Institut de l'Elevage - Idele
 
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusGAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusInstitut de l'Elevage - Idele
 
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageGAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageInstitut de l'Elevage - Idele
 
conception d'un batiment r+4 comparative de defferente ariante de plancher
conception d'un  batiment  r+4 comparative de defferente ariante de plancherconception d'un  batiment  r+4 comparative de defferente ariante de plancher
conception d'un batiment r+4 comparative de defferente ariante de planchermansouriahlam
 
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...Institut de l'Elevage - Idele
 
JTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdfJTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdfInstitut de l'Elevage - Idele
 
Algo II : les piles ( cours + exercices)
Algo II :  les piles ( cours + exercices)Algo II :  les piles ( cours + exercices)
Algo II : les piles ( cours + exercices)Sana REFAI
 
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...Institut de l'Elevage - Idele
 
GAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesGAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesInstitut de l'Elevage - Idele
 
GAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéGAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéInstitut de l'Elevage - Idele
 
comprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestioncomprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestionyakinekaidouchi1
 
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...Institut de l'Elevage - Idele
 
WBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdfWBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdfSophie569778
 
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...Institut de l'Elevage - Idele
 

Dernier (20)

Câblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdfCâblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdf
 
CAP2ER_GC_Presentation_Outil_20240422.pptx
CAP2ER_GC_Presentation_Outil_20240422.pptxCAP2ER_GC_Presentation_Outil_20240422.pptx
CAP2ER_GC_Presentation_Outil_20240422.pptx
 
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
 
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdfJTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
 
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
 
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusGAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
 
JTC 2024 Bâtiment et Photovoltaïque.pdf
JTC 2024  Bâtiment et Photovoltaïque.pdfJTC 2024  Bâtiment et Photovoltaïque.pdf
JTC 2024 Bâtiment et Photovoltaïque.pdf
 
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageGAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
 
conception d'un batiment r+4 comparative de defferente ariante de plancher
conception d'un  batiment  r+4 comparative de defferente ariante de plancherconception d'un  batiment  r+4 comparative de defferente ariante de plancher
conception d'un batiment r+4 comparative de defferente ariante de plancher
 
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
 
JTC 2024 - DeCremoux_Anomalies_génétiques.pdf
JTC 2024 - DeCremoux_Anomalies_génétiques.pdfJTC 2024 - DeCremoux_Anomalies_génétiques.pdf
JTC 2024 - DeCremoux_Anomalies_génétiques.pdf
 
JTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdfJTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdf
 
Algo II : les piles ( cours + exercices)
Algo II :  les piles ( cours + exercices)Algo II :  les piles ( cours + exercices)
Algo II : les piles ( cours + exercices)
 
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
 
GAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesGAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentes
 
GAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéGAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversité
 
comprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestioncomprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestion
 
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
 
WBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdfWBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdf
 
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
 

Héritage dans cpp dev informatique ingenierie

  • 1. L’héritage en C++ Ecole Marocaine des Sciences de l’Ingénieur Marrakech
  • 3. Plan du chapitre ▪ Présentation de concept de l’héritage simple ▪ Mise en œuvre de l’héritage ▪ Utilisation dans une classe dérivée des membres de la classe de base ▪ Redéfinition des fonctions membres ▪ Appel des constructeurs et des destructeurs ▪ Contrôle d’accès ▪ Conversion d’un objet dans un objet d’un type de base
  • 4. Présentation de concept de l’héritage simple ▪ Qu’est ce que l’héritage ? ▪ L’héritage consiste, à partir d’une classe existante A, à définir une nouvelle classe B. ▪ La classe existante A est appelée classe mère, ou classe de base. ▪ La nouvelle classe B est appelée classe fille ou dérivée de la classe A. ▪ On dit que la classe B dérive ou hérite de la classe A. ▪ Une classe fille hérite automatiquement des données et méthodes de sa classe mère sans avoir à les réécrire. ▪ Une classe mère peut avoir plusieurs classe filles. ▪ Une classe fille peut elle même servir de classe mère pour une autre classe fille. ▪ On parle de l’héritage simple, quand une classe fille hérite d’une seule classe mère.
  • 5. Présentation de concept de l’héritage simple ▪ Exemple Classe véhicule Classe DeuxRoues Classe Vélo Classe Moto Classe QuatreRoues Classe Camion Classe voiture
  • 6. Présentation de concept de l’héritage simple ▪ Utilité de l’héritage ▪ L’héritage permet de réutiliser des classes existantes ▪ L’héritage permet d’adapter des classes existantes à ses propres besoins ▪ L’héritage permet de faire évoluer les classes sans avoir à les réécrire de A à Z. ▪ L’héritage permet de moduler les classes et de les spécialiser au fur et à mesure des besoins. ▪ L’héritage permet d’éviter de construire des classes de taille trop importante.
  • 7. Mise en œuvre de l’héritage ▪ La définition d’une classe dérivée d’une classe de base se fait de la manière suivante (héritage simple): class nom classe dérivée : modificateur accès nom classe de base { Déclaration des membres (données et méthodes) de la classes dérivée Définitions des méthodes de la classe dérivée }
  • 8. Mise en œuvre de l’héritage Exemple simple sans constructeur ni destructeur class point{ private: int x, y; public: void initialise(int a, int b){ x=a; y=b; } void deplace(int a, int b){ x=x+a; y=y+b; } void affiche(){ cout<<"Point : "<<x<<" - "<<y<<endl; } }; class point_colore:public point{ int couleur; public: void colorer(int c) { couleur=c; } }; Hérite de main(){ point_colore p; // p de type point_colore p.initialise(12,27); //méthode de la classe point p.colorer(7); p.affiche(); //méthode de la classe point p.deplace(1,2); // méthode de la classe point p.affiche(); // méthode de la classe point } - La déclaration ‘class point_colore : public point’ spécifie que la classe 'point_colore' est dérivée de la classe de base 'point'. - Le mot clé ‘public’ signifie que les membres publics de la classe de base seront des membres public de la classe dérivée.
  • 9. Utilisation dans une classe dérivée des membres de la classe de base ▪ Après avoir fait appel à la fonction ‘ colorer ’, la fonction ‘affiche’ ne donne aucune information sur la couleur d'un point. ▪ Ce qui nous conduit donc a créer une fonction ‘ affiche_c ’ membre de ‘point_colore’ pour afficher les coordonnées x, y et la couleur c. ▪ Or, une classe dérivée n'a pas accès aux membres privés de la classe de base. La solution est donc : void affiche_c(){ cout<<"Point : "<<x<<" - "<<y<<endl; cout<<"En couleur : "<<couleur<<endl; } void affiche_c() { affiche(); //solution accéder à x et y via la méthode affiche qui est public cout<<" en couleur : "<<couleur<<endl; }
  • 10. Utilisation dans une classe dérivée des membres de la classe de base ▪ De même on peut initialiser x, y et couleur en même temps avec une fonction ‘ initialise_c ’ de la classe dérivée 'point_colore'. ▪ Le programme de la classe point_c complet est donc : class point_colore:public point{ int couleur; public: void colorer(int c) { couleur=c; } void affiche_c(){ affiche(); cout<<"en couleur : "<<couleur<<endl; } void initialise_c(int a, int b, int c){ initialise(a,b); couleur= c; } }; int main(){ point_colore p; p.initialise_c(12,27,9); p.colorer(7); p.affiche(); p.affiche_c(); p.deplace(1,2); p.affiche(); p.affiche_c(); }
  • 11. Redéfinition des fonctions membres ▪ Les méthodes 'affiche' de la classe 'point' et 'affiche_c‘ de la classe 'point_colore' font un travail analogue. De même pour les fonctions 'initialise' et 'initialise_c'. ▪ En c++, il est possible de redéfinir la fonction 'affiche‘ ou la fonction 'inialise’ pour la classe dérivée. ▪ Exemple class point_colore:public point { int couleur; public: void colorer(int c) { couleur=c; } void affiche(){ point::affiche(); cout<<"en couleur : "<<couleur<<endl; } void initialise(int a, int b, int c) { point::initialise(a,b); couleur= c; } }; int main(){ point_colore p; p.affiche(); p.initialise(12, 27, 9); p.affiche(); p.point::affiche(); p.deplace(10, 20); p.affiche(); p.colorer(7); p.affiche(); }
  • 12. Contrôle d’accès 2 . les membres protégés d’une classe ▪ Les membres protégés restent inaccessibles à l’utilisateur (comme les membres privés). Mais ils seront accessibles aux membres d'une éventuelle classe dérivée, tout en restant inaccessibles aux utilisateurs de cette classe. ▪ Exemple : supposons qu’on a ▪ On peut donc déclarer dans la classe 'point_colore‘ dérivée de la classe 'point' une fonction 'affiche' qui accède aux membres protégés x et y. class point{ protected: int x, y; public: void initialise(int, int); void deplace(int, int); void affiche(); };
  • 13. Héritage offre plusieurs avantages ▪ Cela évite d'avoir à réécrire le même code à plusieurs reprises. Un ancêtre peut transmettre des propriétés à tous ses descendants. ▪ En termes de codage, cela peut vous faire économiser beaucoup de temps et de travail. ▪ Cela réduit le nombre d'endroits où des bogues pourraient être introduits dans le programme, ainsi vous réduisez le temps de débogage. ▪ Il permet le polymorphisme
  • 14. En pratique, l'héritage fonctionne de plusieurs manières ▪ D'un point de vue descendant, l'héritage orienté objet peut être considéré comme un moyen de prendre une idée plus générale et de la diviser en idées plus spécialisées. ▪ Mais l'héritage peut également fonctionner d'un point de vue ascendant, où vous commencez avec la progéniture et décidez quel type d'ancêtre ils ont en commun. Que ce soit descendant ou ascendant, le résultat final est un arrangement similaire de classes.
  • 15. Contrôle d'accès et héritage ▪ Une classe dérivée peut accéder à tous les membres non privés de sa classe de base. ▪ Les membres de la classe de base qui ne devraient pas être accessibles aux fonctions membres des classes dérivées doivent être déclarés privés dans la classe de base. ▪ Selon le modificateur d'accès utilisé pendant l'héritage, la disponibilité des membres de la classe Super class dans la sous-classe change. Il peut être soit private, protected ou public.
  • 16. Héritage public ▪ Lors de la dérivation public d'une sous-classe d'une classe de base, les membres publiques de la classe de base deviennent des membres publiques de la classe dérivée et les membres protégés de la classe de base deviennent des membres protégés de la classe dérivée. ▪ Les membres privés d'une classe de base ne sont jamais accessibles directement à partir d'une classe dérivée, mais sont accessibles via des appels aux membres publiques et protégés de la classe de base.
  • 17. #include <iostream> using namespace std; class Base { private: int pvt ; protected: int prot ; public: int pub ; Base(){pvt=1; prot=2;pub=3;} // function to access private member int getPVT() { return pvt; } }; class PublicDerived : public Base { public: // function to access protected member from Base int getProt() { return prot; } // function to access public member from Base int getPub() { return pub; } }; int main() { PublicDerived object1; //cout << "Private cannot be accessed." << endl; cout << "Private = " << object1.getPVT() << endl; cout << "Protected = " << object1.getProt() << endl; cout << "Public = " << object1.getPub() << endl; return 0; }
  • 18. Exemple: Discussion selon le mode de dérivation: accès direct à un champ #include <iostream> using namespace std; class Base { public: int pub ; public: Base(){pub=3;}}; class PublicDerived : protected Base { public: int getPub() { return pub; } }; int main() { PublicDerived object1; object1.pub; cout << "Public = " << object1.getPub() << endl; return 0; }
  • 19. Héritage protected ▪ Lors de la dérivation protected d'une sous-classe d'une classe de base, les membres publiques et protégés de la classe de base deviennent des membres protégés de la classe dérivée.
  • 20. Exemple #include <iostream> using namespace std; class Base { private: int pvt ; protected: int prot ; public: int pub ; Base(){pvt=1; prot=2;pub=3;} // function to access private member int getPVT() { return pvt; } }; class ProtectedDerived : protected Base { public: // function to access protected member from Base int getProt() { return prot; } // function to access public member from Base int getPub() { return pub; } }; int main() { ProtectedDerived object1; cout << "Private cannot be accessed." << endl; //cout << "Private = " << object1.getPVT() << endl; cout << "Protected = " << object1.getProt() << endl; cout << "Public = " << object1.getPub() << endl; return 0; } Lorsque vous utilisez l'héritage protégé, les membres publics et protégés de la classe de base deviennent des membres protégés de la classe dérivée. Cela signifie que les membres publics de la classe de base deviennent accessibles en tant que membres protégés dans la classe dérivée. Dans votre code, getPVT() est une fonction membre de la classe Base qui accède à la variable privée pvt. Étant donné que ProtectedDerived hérite de Base en mode protégé, même les membres privés de Base deviennent des membres protégés de ProtectedDerived et ne sont donc pas accessibles directement en dehors de la classe dérivée.
  • 21. Héritage private ▪ Lors de la dérivation private d'une sous-classe d'une classe de base, les membres publiques et protégés de la classe de base deviennent des membres privés de la classe dérivée. ▪ Syntaxe:
  • 22. #include <iostream> using namespace std; class Base { private: int pvt ; protected: int prot ; public: int pub ; Base(){pvt=1; prot=2;pub=3;} // function to access private member int getPVT() { return pvt; } }; class PrivateDerived : private Base { public: // function to access protected member from Base int getProt() { return prot; } // function to access public member from Base int getPub() { return pub; } }; int main() { PrivateDerived object1; cout << "Private cannot be accessed." << endl; //cout << "Private = " << object1.getPVT() << endl; cout << "Protected = " << object1.getProt() << endl; cout << "Public = " << object1.getPub() << endl; return 0; }
  • 23. Porquoi l’héritage privé ▪ L'objectif principal de cet héritage est de créer une relation "est implémenté en termes de" plutôt qu'une relation "est un type de" (comme c'est le cas avec l'héritage public). ▪ Quelques points clés concernant l'héritage privé : ▪ Restreindre l'accès : Les membres publics et protégés de la classe de base deviennent privés dans la classe dérivée. Cela signifie que ces membres ne sont pas accessibles en dehors de la classe dérivée. ▪ Implémentation de comportement : L'héritage privé est souvent utilisé pour réutiliser l'implémentation d'une classe de base dans une classe dérivée sans exposer l'interface de la classe de base. ▪ Sécurité et encapsulation : Cela renforce l'encapsulation en limitant l'accès aux membres de la classe de base, empêchant ainsi les modifications involontaires de la classe dérivée par des utilisateurs extérieurs. ▪ Sous-classe spécialisée : L'héritage privé peut être utile pour créer des sous-classes spécialisées qui utilisent l'implémentation de la classe de base, mais qui ne doivent pas être utilisées directement en dehors de la classe dérivée.
  • 24. ▪ L'héritage protégé en programmation orientée objet offre un niveau d'encapsulation intermédiaire entre l'héritage public et l'héritage privé. Lorsque vous utilisez l'héritage protégé, les membres publics de la classe de base deviennent des membres protégés dans la classe dérivée, tandis que les membres protégés de la classe de base restent protégés dans la classe dérivée. ▪ Quelques raisons d'utiliser l'héritage protégé : ▪ Encapsulation contrôlée : L'héritage protégé permet de contrôler l'accès aux membres de la classe de base. Les membres publics de la classe de base deviennent accessibles uniquement à la classe dérivée et à ses classes dérivées ultérieures, ce qui renforce l'encapsulation tout en permettant une certaine extension. ▪ Relation "est implémenté en termes de" : Comme avec l'héritage privé, l'héritage protégé est souvent utilisé pour définir une relation "est implémenté en termes de". Cela signifie que la classe dérivée implémente certaines fonctionnalités en utilisant des éléments de la classe de base sans exposer directement l'interface de la classe de base. ▪ Réutilisation du code : L'héritage protégé permet à la classe dérivée d'utiliser et de réutiliser les fonctionnalités et le comportement de la classe de base tout en limitant l'accès aux parties sensibles ou critiques de cette classe. ▪ Spécialisation contrôlée : Il permet de créer des classes dérivées spécialisées qui peuvent étendre et modifier le comportement des classes de base sans que ces modifications ne soient directement visibles à l'extérieur. ▪ Souplesse dans la conception : L'héritage protégé offre une certaine souplesse dans la conception des classes, permettant de créer des hiérarchies de classes bien structurées et modifiables avec un niveau de contrôle supplémentaire.
  • 25. Contrôle d’accès 1 . L’héritage privé ▪ Pour que l’utilisateur d’une classe dérivée n’ait pas accès aux membres publics de sa classe de base, il suffit de remplacer le mot ‘public’ par ‘private’ dans sa déclaration. ▪ Exemple ▪ Si on a :‘point_colore O(12, 4, 6) ;’ les appels suivants sont rejetés : ‘O.affiche() ;’ ou ‘O.point::affiche();’ ‘O.deplace(1,5);’ ou ‘O.point::depace(1,5);’ ▪ Cette technique de fermeture d’accès à la classe de base ne sera employée que dans des cas précis, lorsque par exemple toutes les fonctions utiles de la classe de base sont redéfinies dans la classe dérivée, et qu’il n’y a aucune raison de laisser l’utilisateur accéder aux anciennes. class point{ int x, y; public: void initialise (inta,int b) { x=a; y=b; } void deplace (inta,intb) { x=x+a; y=y+b;} void affiche() { ……………………… } }; class point_colore:private point { int couleur; public: void colorer(int c) { couleur=c; } };
  • 26.
  • 27. Autre Exemple d’héritage simple #include <iostream> using namespace std; //Classe de base class Vehicule { public: int id_vh; string marque; int vitesse; }; // Sous-classe héritant de la classe de base (véhicule) class Voiture : public Vehicule { public: int id_vt; }; //fonction main int main() { Voiture v; // L'objet de la classe enfant a tous les membres de données v.id_vh = 3; v.id_vt = 58; v.marque = "Land"; v.vitesse = 300; cout << "ID de Voiture est : " << v.id_vh << endl; cout << "ID de Vehicule est : " << v.id_vt << endl; cout << "La marque : " << v.marque << endl; cout << "La vitesse : " << v.vitesse << endl; return 0; }
  • 29. Contrôle d’accès 3 . Tableau récapitulatif sur l’héritage et les modificateurs d’accées Classe de base Modificateur d’accès Classe dérivées public public public public private private protected public protected protected private private private public non accessible private private non accessible
  • 30. Appel des constructeurs et des destructeurs ▪ Exemple ▪ Si on a : class point{ int x, y; public: point(int, int) ; ……………………………. ………………………… } ; class point_colore:public point{ int couleur; public: point_colore(int, int, int) ; …………………………. ……………………….. } ;
  • 31. Appel des constructeurs et des destructeurs #include <iostream> using namespace std; class Base { int a; public: Base() : a(0) {cout<<"construction objet classe de base"<<" "<<"a="<<a<<endl;} Base(int A) : a(A) {cout<<"construction objet classe de base"<<" "<<"a="<<a<<endl;} ~Base(){cout<<"destruction partie classe de base"<<" a="<<a<<endl;} }; class Derived : public Base{ int b; public: Derived(): b(0) {cout<<"construction objet classe Derivee"<<" "<<"b="<<b<<endl;} // appel implicite à Base() Derived(int i, int j) : Base(i), b(j) {cout<<"construction objet classe Derivee"<<" "<<"b="<<b<<endl;} // appel explicite ~Derived(){cout<<"destruction partie classe derivee"<<" b="<<b<<endl;} }; int main() { Derived D; Derived DD(3,4); return 0; }
  • 32.
  • 33.
  • 34.
  • 35. #include <iostream> using namespace std; //************Class point****** class point{ int x,y; public: point(int abs=0,int ord=0){ cout<<"++ Construct Point:"<<abs<<" "<<ord<<endl; x=abs; y=ord; } ~point(){ cout<<"-- Destr Point:"<<x<<" "<<y<<endl; } }; //************Class pointcol****** class pointcol: public point{ short couleur; public: pointcol(int abs=0,int ord=0, short c=1):point(abs,ord){ cout<<"++ Construct PointCol:"<<abs<<" "<<ord<<" "<<c<<endl; couleur=c; } ~pointcol(){ cout<<"-- Destr Couleur:"<<couleur<<endl; } }; int main() { pointcol a(10,15,3); pointcol b(2,3); pointcol c(12); pointcol * adr; adr=new pointcol(12,25); delete adr; return 0; }
  • 36. Appel des constructeurs et des destructeurs ▪ Pour créer un objet de la classe ‘point_colore’, il faut tout d’abord créer un objet de la classe ‘point’, donc faire appel au constructeur de la classe ‘point’, le compléter par ce qui est spécifique a la classe ‘point_colore’ et faire appel au constructeur de la classe ‘point_colore’. ▪ Si on souhaite que le constructeur de la classe ’point_colore’ retransmette au constructeur de la classe ‘point’ les premières informations reçues, on écrira : ▪ Ainsi, la déclaration : ‘point_colore(2, 4, 5) ;’ entraînera : ▪ l’appel du constructeur ’point’ qui recevra les valeurs 2 et 4. ▪ l’appel du constructeur ’point_colore’ qui recevra les valeurs 2, 4 et 5. point_colore(int a, int b, int c):point(a, b) Nom de la classe dérivée (paramètres):nom de la classe mère(paramètres) Syntaxe : Exemple :
  • 37. Appel des constructeurs et des destructeurs ▪ Il est toujours possible de mentionner les valeurs par défaut : ▪ Donc la déclaration ‘point_colore(17) ;’ entraîne : ▪ appel du constructeur ‘point’ avec les valeurs 17 et 2. ▪ appel du constructeur ‘point_colore’ avec les valeurs 17 , 2 et 5. point_colore(int a=0, int b=2, int c=5):point(a,b)
  • 38. Appel des constructeurs et des destructeurs 1 . Exercice Reprendre le programme précédent en ajoutant les constructeurs et les destructeurs correspondants, tout en affichant les moments de construction et de destruction des objets.
  • 39. Appel des constructeurs et des destructeurs 2 . D’une manière générale ▪ Si la classe de base ne possède pas de constructeur, aucun problème particulier ne se pose. De même si elle ne possède pas de destructeur. ▪ En revanche, si la classe dérivée ne possède pas de constructeur, alors que la classe de base en comporte, le problème sera posé lors de la transmission des informations attendues par le constructeur de la classe de base. La seule situation acceptable est celle où la classe de base dispose d’un constructeur sans arguments. ▪ Lors de la transmission d’informations au constructeur de la classe de base, on peut utiliser des expressions ou des arguments. ▪ Exemple pointcolore(int a=5, int b=5, int c=4):point(a*2, b*5);
  • 40. Appel des constructeurs et des destructeurs 3 . Cas du constructeur de recopie Compléter le programme précédent en ajoutant les constructeurs par recopie.
  • 41. Conversion d'un objet dérivé dans un objet d'un type de base ▪ Si on a : ▪ l'affectation ‘O1=O2 ;’ est juste. ▪ l'affectation ‘O2=O1 ;’ est rejetée (si O2 a des arguments définis par défaut, on aura pas de problème). point O1; point_colore O2;
  • 42. Exercice 1. Créer une classe de base Article. Un article possède deux champs privés: • Nom : string • Prix : double Et les opérations publiques : • getPrix() : pour retourner le prix de l'article • setPrix(double) : pour changer le prix de l'article • afficher() : permet d’afficher le prix. 2. Réaliser ensuite une classe ArticleEnSolde, dérivée de la classe Article. Cette sous-classe comprend une information additionnelle: • remise : pourcentage de réduction sur le prix d'origine • setRemise(entier) pour changer la remise. La classe va redéfinir la méthode getPrix(), afin de tenir compte du solde. Elle va également redéfinir la méthode afficher(), afin que l'affichage donne également le pourcentage de remise sur le prix d'origine.
  • 43. #include<iostream> using namespace std; class Article{ protected: string nom; double prix; public: Article():nom(""),prix(0){}; Article(string a,double b):nom(a),prix(b){}; double getPrix(){return prix;} void setPrix(double a){prix=a;} void afficher(){cout<<"le prix d article "<<nom<<" est : "<<prix<<endl; } }; class ArticleEnSolde: public Article{ double remise; public: ArticleEnSolde():remise(0){}; ArticleEnSolde(string nom,double prix,double a):Article(nom,prix){ remise=a; }; void setRemise(double a){remise=a;} double getPrix(){return prix;} double RemiseSurPrixOrigine(){return prix*remise/100;} void afficher(){ double px=prix-prix*remise/100; Article::afficher();cout<<"le prix d article apres remise est : "<<px<<endl;} }; main(){ ArticleEnSolde B("chaise",100,20); B.afficher(); }
  • 45. Plan du chapitre ▪ Mise en œuvre de l’héritage multiple ▪ Les classes virtuelle ▪ Appel des constructeurs et des destructeurs dans le cas des classes virtuelles
  • 46. Mise en œuvre de l’héritage multiple ▪ L’exemple suivant met en évidence la notion d’héritage multiple à travers la classe ‘point_colore’ héritant des classes ‘point’ et ‘coul’.
  • 47. Mise en œuvre de l’héritage multiple class point { int x,y; public: point(int a, int b){ x=a ; y=b ; cout<<’’Constructeur de point ’’ ; } ~point() { cout<<’’Destructeur de point ’’ ; } void affiche() { cout<<’’point ’’ <<x<<’’-‘’<<y ; } }; class coul { int couleur ; public : coul(int c){ couleur=c ; cout<<’’Construction de coul ’’ ; } ~coul() { cout<<’’Destruction de coul ’’ ; } void affiche() { cout<<’’Couleur : ’’ <<couleur<<endl ; } } ; class point_colore:public point, public coul { public: point_colore (int a, int b, int c):point (a,b) , coul(c){ cout<<’’construction de pointcoloren’’ ; } ~point_colore() { cout<<’’destruction de pointcoloren’’ ; } void affiche() { point::affiche(); coul::affiche(); } }; void main() { point_colore o(100, 200, 3); o.affiche(); } Exemple
  • 48. Les classes virtuelle ▪ Si on a : ▪ Donc les déclarations suivantes : ▪ Impliquent que la classe ‘D’ hérite deux fois de la classe ‘A’, donc les membres de ‘A’ vont apparaître deux fois dans ‘D’. ▪ les fonctions membres ne sont pas réellement dupliquées. ▪ les données membres seront effectivement dupliquées. class A { int x, y ; ………………. ………………. }; class B:public A { ……………… ……………… }; class D:public B, public C { …………. .………… }; class C:public A { ……………… ……………… };
  • 49. Les classes virtuelle ▪ Solution ▪ si on ne veut pas de cette duplication, on précisera la classe ‘A’ comme classe virtuelle dans les déclarations des classes ‘B’ et ‘C’. class A { int x, y ; ………………. ………………. }; class B:public virtual A { ……………… ……………… }; class D:public B, public C { …………. .………… }; class C:public virtual A { ……………… ……………… }; - le mot-clé ‘virtual’ apparaît dans la classe ‘B’ et la classe ‘C’. - le mot-clé ‘virtual’ peut être placé avant ou après le mot-clé ‘public’. Remarques :
  • 50. ▪ Si ‘A’ n’est pas déclarée ‘virtual’ dans les classes ‘B’ et ‘C’, les constructeurs seront appelés dans l’ordre : ‘A1’, ‘B’, ‘A2’, ‘C’ et ‘D’. ▪ Si ‘A’ a été déclarée ‘virtual’ dans ‘B’ et ‘C’, on ne construira qu’un seul objet de type de ‘A’ (et non pas deux objets). Quels arguments faut-il transmettre alors au constructeur ? Ceux prévus par ‘B’ ou ceux prévus par ‘C’ ? Question : Appel des constructeurs et des destructeurs dans le cas des classes virtuelles
  • 51. ▪ Le choix des informations à transmettre au constructeur de ‘A’ se fait, non plus dans ‘B’ ou ‘C’, mais dans ‘D’. Pour ce faire, C++ autorise (uniquement dans ce cas) à spécifier, dans le constructeur de ‘D’, des informations destinées à ‘A’. ▪ Ainsi, on peut avoir : D(int a, int b, int c):B(a, b, c), A(a, b) ▪ Bien entendu, il sera inutile de préciser des informations pour ‘A’ au niveau des constructeurs ‘B’ et ‘C’. ▪ En ce qui concerne l’ordre des appels, le constructeur d’une classe virtuelle est toujours appelé avant les autres. Dans notre cas, on a l’ordre ‘A’, ‘B’, ‘C’ et ‘D’. Appel des constructeurs et des destructeurs dans le cas des classes virtuelles
  • 52. ▪ L’ordre des appels des constructeurs est : B, A, C, D et E. Exemple : Appel des constructeurs et des destructeurs dans le cas des classes virtuelles