INTRODUCTION AU LANGAGE C++zhengyi.cao.free.fr/doc/Cours/M1/Cpp/Cours_C++/cours10.pdf · PROGRAMME...

Preview:

Citation preview

INTRODUCTION AU LANGAGE C++

HERITAGE MULTIPLE ET FLOTS

26 Mars 2012

Dr Bernard Ries LAMSADE LANGAGE C++

PROGRAMME

1 Elements de base2 Les structures de controle3 Fonctions et programmation modulaire4 References, pointeurs et tableaux5 Allocation dynamique et introduction aux classes6 Proprietes des methodes7 Constructeurs et destructeurs8 Fonctions amies et surcharge des operateurs9 Heritage simple10 Heritage multiple et flots

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS

L’heritage est une technique extremement efficace pour creer desclasses plus specialisees, appelees sous-classes ou classesderivees, a partir de classes plus generales deja existantes,appelees alors sur-classes ou classes de base.

Plus precisement, lorsqu’une classe derivee B est creee a partird’une classe A, alors B va heriter de l’ensemble des attributs etdes methodes de A, i.e., ces attributs et methodes vont etre”disponibles” pour B sans que l’on ait besoin de les redefinirexplicitement dans B.

L’heritage permet de definir implicitement certains des attributs etdes methodes de la classe derivee en reutilisant ceux deja definisdans la classe de base. Cela permet donc une reduction deredondance pour les programmes produits.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (2)

Les instances d’une classe derivee vont heriter a la fois desattributs definis dans classe derivee et des attributs definis dansl’ensemble des classes dont la classe derivee herite (i.e. sa classe debase, la classe de base de cette classe de base, etc...).

De meme, les methodes ”accessibles” pour les instances sontegalement a la fois celles definies dans la classe derivee et cellesdefinies dans toutes les classes dont la classe derivee herite.

En fait, les notions de specialisation (i.e. creation de classesderivees) et d’heritage permettent de creer un reseau dedependances entre les classes organise en une structure d’arbre(dans le cas de l’heritage simple) ou chacun des noeuds (quirepresente une classe donnee) herite de l’ensemble des noeuds quile separent de la racine de l’arbre des classes.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (3)

Supposons par exemple que l’on veuille etendre la classeRectangle en lui ajoutant le nouvel attribut m couleur.

Une facon de proceder est de creer une nouvelle classe, parexemple Rectangle colore, definie comme une classe derivee deRectangle et contenant le nouvel attribut m couleur.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (4)

1 class Rectangle2 {3 float m_hauteur;4 float m_largeur;5

6 public:7

8 void initialise (float, float);9 void affichage();

10 float surface();11 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (5)

Voici a quoi pourrait correspondre la classe Rectangle colore :1 class Rectangle_colore : public Rectangle2 {3 int m_couleur;4

5 public:6

7 void colore (int c)8 {9 m_couleur=c;

10 }11 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (6)

La declaration1 class Rectangle_colore : public Rectangle

specifie que Rectangle colore est une classe derivee de la classede base Rectangle.

Le mot-cle public signifie que les membres publics de la classede base (Rectangle) seront des membres publics de la classederivee (Rectangle colore).

Il s’agit la de l’utilisation la plus frequente de l’heritage enP.O.O.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (7)

1 Rectangle_colore R1, R2;

Chaque objet de type Rectangle colore peut faire appel :

aux methodes publiques de Rectangle colore ;aux methodes publiques de la classe de base Rectangle.

1 R1.initialise(4.5,6.9);2 R1.affichage();3 R2.colore(5);4 R2.surface();

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (8)

Regle adoptee par C++ :

Une methode d’une classe derivee n’a pas acces auxmembres prives de sa classe de base !

Lorsqu’une methode est definie dans une classe, elle masquetoutes les methodes de meme nom de la classe de base (etdes classes ascendantes). Autrement dit, la recherche d’unefonction (surdefinie ou non) se fait dans une seule portee,soit celle de la classe concernee, soit celle de la classe debase (ou une classe ascendante), mais jamais dans plusieursclasses a la fois.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (9)

Pour le moment, on a vu la situation d’heritage la plusnaturelle :

la classe derivee (c’est-a-dire les methodes de celle-ci) aacces aux membres publics de la classe de base ;les utilisateurs de la classe derivee (c’est-a-dire tout objetdu type de la classe derivee) ont acces a ses membrespublics ainsi qu’aux membres publics de sa classe debase.

C++ permet d’intervenir en partie sur ces deux sortesd’autorisation d’acces, et ce a deux niveaux :

lors de la conception de la classe de base ;lors de la conception de la classe derivee.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (10)

public : les membres publics sont accessibles non seulementaux methodes ou aux fonctions amies, mais egalement al’utilisateur de la classe (c’est-a-dire tout objet du type decette classe) ;private : les membres prives ne sont accessibles qu’auxmethodes (publiques ou privees) et aux fonctions amies dela classe ;protected : les membres proteges restent inaccessibles al’utilisateur de la classe pour qui ils apparaissent comme desmembres prives ; mais ils seront accessibles aux membresd’une eventuelle classe derivee, tout en restant dans tousles cas inaccessibles aux utilisateurs de cette classe.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (11)

De maniere generale, en P.O.O., on considere qu’un objet d’uneclasse derivee peut ”remplacer” un objet d’une classe debase.

Cette idee repose sur le fait que tout ce qu’on trouve dans uneclasse de base se trouve egalement dans la classe derivee.

Par exemple, un rectangle colore peut toujours etre traite commeun rectangle (l’inverse n’etant pas vraie).

Tout objet de type Rectangle colore est un Rectangle, mais toutobjet de type Rectangle n’est pas un Rectangle colore !

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (12)

On retrouve cette compatibilite entre classe de base et classederivee en C++, mais elle ne s’applique que dans le cas dederivation publique !

Cette compatibilite se resume a l’existence de conversionsimplicites :

d’un objet d’un type derive dans un objet de type debase ;d’un pointeur sur une classe derivee en un pointeur surune classe de base.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (13)

1) La classe derivee ne definit pas de constructeur de recopie

Il y aura appel du constructeur de recopie par defaut de B.Cette recopie se fait membre par membre.

Ici, cela veut dire que la ”partie” de B appartenant a la classeA sera traitee comme un membre de type A.

On cherchera donc a appeler le constructeur de recopie de Apour les attributs correspondants.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (14)

2) La classe derivee definit un constructeur de recopie

Le constructeur de recopie de B sera alors naturellement appele.

Mais C++ n’a pas prevu un appel automatique de constructeur dela classe de base dans ce cas.

Le constructeur de recopie de la classe derivee doit prendreen charge l’integralite de la recopie de l’objet, et nonseulement de sa partie non heritee !

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (15)

1 B (const B& b) : A(b)2 {3 ...4 }5 // b est converti dans le type A pour etre6 // transmis au constr. de recopie de A

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (16)

1) La classe derivee ne surdefinit pas =

L’affectation de deux objets de type B se deroule membre parmembre en considerant que la partie heritee de A constitue unmembre.

Ainsi, les membres propres a B sont traites par l’affectation prevuepour leur type (par defaut ou surdefinie).

La partie heritee de A est traitee par l’affectation prevue dansla classe A :

par l’operateur = surdefini dans A s’il existe ;par l’affectation par defaut de A si l’operateur = n’a pasete redefini du tout.

On retrouve un comportement tout a fait analogue a celui decritdans le cas du constructeur de recopie !

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (17)

2) La classe derivee surdefinit =

L’affectation de deux objets de type B fera alors necessairementappel a l’operateur = defini dans B. Celui de A ne sera pasappele, meme s’il a ete surdefini.

Il faudra donc que l’operateur = de B prenne en charge toutce qui concerne l’affectation d’objets de type B, y comprispour ce qui est des membres herites de A.

Si l’on veut profiter de l’operateur = defini dans A, il faudral’appeler explicitement !⇒ utiliser les possibilite de conversions de pointeurs

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (18)

1 B& operator = (const B& b)2 {3 A* ad1, ad2;4 ad1=this; // conversion de pointeur5 ad2=&b; // conversion de pointeur6 *ad1=*ad2; // affectation de la "partie A" de B7

8 // affectation de la partie propre a B9

10 return *this;11 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE : RAPPELS (19)

On convertit les pointeurs (this et &b) sur des objets de type B endes pointeurs sur des objets de type A.

Ensuite il suffit de realiser une affectation entre les nouveauxobjets pointes (*ad1 et *ad2) pour entrainer l’appel del’operateur = de la classe A.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE

Grace a l’heritage multiple, une classe peut etre derivee deplusieurs classes de base.

La plupart des choses vues dans le cas de l’heritage simples’etendent a l’heritage mulitple. Mais plusieurs questions seposent :

1 comment exprimer une dependance multiple ?2 comment sont appeles les constructeurs et destructeurs

(ordre, transmission d’information, etc) ?3 comment regler des conflits ?

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE

Grace a l’heritage multiple, une classe peut etre derivee deplusieurs classes de base.

La plupart des choses vues dans le cas de l’heritage simples’etendent a l’heritage mulitple. Mais plusieurs questions seposent :

1 comment exprimer une dependance multiple ?2 comment sont appeles les constructeurs et destructeurs

(ordre, transmission d’information, etc) ?3 comment regler des conflits ?

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE

Grace a l’heritage multiple, une classe peut etre derivee deplusieurs classes de base.

La plupart des choses vues dans le cas de l’heritage simples’etendent a l’heritage mulitple. Mais plusieurs questions seposent :

1 comment exprimer une dependance multiple ?

2 comment sont appeles les constructeurs et destructeurs(ordre, transmission d’information, etc) ?

3 comment regler des conflits ?

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE

Grace a l’heritage multiple, une classe peut etre derivee deplusieurs classes de base.

La plupart des choses vues dans le cas de l’heritage simples’etendent a l’heritage mulitple. Mais plusieurs questions seposent :

1 comment exprimer une dependance multiple ?2 comment sont appeles les constructeurs et destructeurs

(ordre, transmission d’information, etc) ?

3 comment regler des conflits ?

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE

Grace a l’heritage multiple, une classe peut etre derivee deplusieurs classes de base.

La plupart des choses vues dans le cas de l’heritage simples’etendent a l’heritage mulitple. Mais plusieurs questions seposent :

1 comment exprimer une dependance multiple ?2 comment sont appeles les constructeurs et destructeurs

(ordre, transmission d’information, etc) ?3 comment regler des conflits ?

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (2)

Considerons la situation ou une classe Rectangle colore herite dedeux autres classes nommees Rectangle et Couleur :

1 class Rectangle2 {3 private:4 float m_hauteur;5 float m_largeur;6 public:7 Rectangle (float, float);8 ˜Rectangle ();9 void affichage ();

10 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (2)

Considerons la situation ou une classe Rectangle colore herite dedeux autres classes nommees Rectangle et Couleur :

1 class Rectangle2 {3 private:4 float m_hauteur;5 float m_largeur;6 public:7 Rectangle (float, float);8 ˜Rectangle ();9 void affichage ();

10 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (3)

1 class Couleur2 {3 private:4 int m_couleur;5 public:6 Couleur (int);7 ˜Couleur ();8 void affichage ();9 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (4)

Alors la classe Rectangle colore est declaree de la manieresuivante :

1 class Rectangle_colore: public Rectangle, public Couleur2 {3 ...4 };

Ainsi, on mentionne simplement les classes de base sous formed’une liste.

Le constructeur de la classe Rectangle colore doit pouvoirtransmettre des informations aux constructeurs des classes de base(comme dans l’heritage simple) :

1 Rectangle_colore (...): Rectangle (...), Couleur (...)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (4)

Alors la classe Rectangle colore est declaree de la manieresuivante :

1 class Rectangle_colore: public Rectangle, public Couleur2 {3 ...4 };

Ainsi, on mentionne simplement les classes de base sous formed’une liste.

Le constructeur de la classe Rectangle colore doit pouvoirtransmettre des informations aux constructeurs des classes de base(comme dans l’heritage simple) :

1 Rectangle_colore (...): Rectangle (...), Couleur (...)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (4)

Alors la classe Rectangle colore est declaree de la manieresuivante :

1 class Rectangle_colore: public Rectangle, public Couleur2 {3 ...4 };

Ainsi, on mentionne simplement les classes de base sous formed’une liste.

Le constructeur de la classe Rectangle colore doit pouvoirtransmettre des informations aux constructeurs des classes de base(comme dans l’heritage simple) :

1 Rectangle_colore (...): Rectangle (...), Couleur (...)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (5)

Ainsi les constructeurs sont appeles dans l’ordre suivant :

1 constructeur de Rectangle ;2 constructeur de Couleur ;3 constructeur de Rectangle colore.

Les destructeurs eventuels seront appeles dans l’ordre inverse lorsde la destruction d’un objet de type Rectangle colore.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (5)

Ainsi les constructeurs sont appeles dans l’ordre suivant :

1 constructeur de Rectangle ;2 constructeur de Couleur ;3 constructeur de Rectangle colore.

Les destructeurs eventuels seront appeles dans l’ordre inverse lorsde la destruction d’un objet de type Rectangle colore.

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (6)

On peut definir une methode affichage() dans la classeRectangle colore qui utilise les deux autres methodes affichage()des classes de base.

1 void affichage()2 {3 Rectangle::affichage();4 Couleur::affichage();5 ...6 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (6)

On peut definir une methode affichage() dans la classeRectangle colore qui utilise les deux autres methodes affichage()des classes de base.

1 void affichage()2 {3 Rectangle::affichage();4 Couleur::affichage();5 ...6 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (7)

Considerons maintenant la situation ou une classePoint col masse herite de deux autres classes nommees Point colet Point masse qui toutes les deux heritent de la classe Point :

1 class Point2 {3 int m_x, m_y;4 ...5 };6

7 class Point_col: public Point {...};8 class Point_masse: public Point {...};9

10 class Point_col_masse: public Point_col, publicPoint_masse

11 {12 ...13 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (7)

Considerons maintenant la situation ou une classePoint col masse herite de deux autres classes nommees Point colet Point masse qui toutes les deux heritent de la classe Point :

1 class Point2 {3 int m_x, m_y;4 ...5 };6

7 class Point_col: public Point {...};8 class Point_masse: public Point {...};9

10 class Point_col_masse: public Point_col, publicPoint_masse

11 {12 ...13 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (8)

Ainsi, la classe Point col masse herite deux fois de la classePoint ! Donc les membres de la classe Point vont apparaitre deuxfois dans la classe Point col masse ! Alors que ceci est sansimportance pour les methodes, la situation est differente pour lesattributs qui sont donc reellement dupliques dans tous les objets dela classe Point col masse.

Si l’on veut effectivement garder deux jeux de donnees de la classePoint, alors il suffit de distinguer les attributs en utilisantl’operateur de resolution de portee :

1 Point::Point_col::m_x;2 Point::Point_masse::m_x;

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (8)

Ainsi, la classe Point col masse herite deux fois de la classePoint ! Donc les membres de la classe Point vont apparaitre deuxfois dans la classe Point col masse ! Alors que ceci est sansimportance pour les methodes, la situation est differente pour lesattributs qui sont donc reellement dupliques dans tous les objets dela classe Point col masse.

Si l’on veut effectivement garder deux jeux de donnees de la classePoint, alors il suffit de distinguer les attributs en utilisantl’operateur de resolution de portee :

1 Point::Point_col::m_x;2 Point::Point_masse::m_x;

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (9)

1 Point::Point_col::m_x;2 Point::Point_masse::m_x;3

4 //si Point_col et Point_masse n’ont pas de m_x:5

6 Point_col::m_x;7 Point_masse::m_x;

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (10)

En general, on ne veut pas de duplication des donnees, c’est-a-direon ne veut avoir qu’un seul jeu de donnees de la classe Point.

Dans ce cas, on doit preciser dans les declarations des classesPoint col et Point masse que la classe Point est ”virtuelle” enutilisant le mot cle virtual.

1 class Point {...};2

3 class Point_col: public virtual Point {...};4 class Point_masse: public virtual Point {...};5

6 class Point_col_masse: public Point_col, publicPoint_masse

7 {8 ...9 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (10)

En general, on ne veut pas de duplication des donnees, c’est-a-direon ne veut avoir qu’un seul jeu de donnees de la classe Point.

Dans ce cas, on doit preciser dans les declarations des classesPoint col et Point masse que la classe Point est ”virtuelle” enutilisant le mot cle virtual.

1 class Point {...};2

3 class Point_col: public virtual Point {...};4 class Point_masse: public virtual Point {...};5

6 class Point_col_masse: public Point_col, publicPoint_masse

7 {8 ...9 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (10)

En general, on ne veut pas de duplication des donnees, c’est-a-direon ne veut avoir qu’un seul jeu de donnees de la classe Point.

Dans ce cas, on doit preciser dans les declarations des classesPoint col et Point masse que la classe Point est ”virtuelle” enutilisant le mot cle virtual.

1 class Point {...};2

3 class Point_col: public virtual Point {...};4 class Point_masse: public virtual Point {...};5

6 class Point_col_masse: public Point_col, publicPoint_masse

7 {8 ...9 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (11)

Ainsi un seul objet de type Point ne sera cree.

Mais quels arguments faut-il alors transmettre au constructeur ?Ceux prevus par Point col ou ceux prevus par Point masse ?

En fait, dans le cas d’une derivation virtuelle, il faut specifierdans le constructeur de la classe Point col masse lesinformations destinees a Point !

1 Point_col_masse (...): Point(...), Pointcol(...),Point_masse(...)

2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (11)

Ainsi un seul objet de type Point ne sera cree.

Mais quels arguments faut-il alors transmettre au constructeur ?Ceux prevus par Point col ou ceux prevus par Point masse ?

En fait, dans le cas d’une derivation virtuelle, il faut specifierdans le constructeur de la classe Point col masse lesinformations destinees a Point !

1 Point_col_masse (...): Point(...), Pointcol(...),Point_masse(...)

2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (11)

Ainsi un seul objet de type Point ne sera cree.

Mais quels arguments faut-il alors transmettre au constructeur ?Ceux prevus par Point col ou ceux prevus par Point masse ?

En fait, dans le cas d’une derivation virtuelle, il faut specifierdans le constructeur de la classe Point col masse lesinformations destinees a Point !

1 Point_col_masse (...): Point(...), Pointcol(...),Point_masse(...)

2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (11)

Ainsi un seul objet de type Point ne sera cree.

Mais quels arguments faut-il alors transmettre au constructeur ?Ceux prevus par Point col ou ceux prevus par Point masse ?

En fait, dans le cas d’une derivation virtuelle, il faut specifierdans le constructeur de la classe Point col masse lesinformations destinees a Point !

1 Point_col_masse (...): Point(...), Pointcol(...),Point_masse(...)

2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (13)

1 class point2 { int x, y ;3 public :4 point (int abs, int ord)5 {6 cout << "Point " << abs << " " << ord << endl;7 x=abs ; y=ord;8 }9 void affiche ()

10 {11 cout << "Coordonnees : " << x << " " << y << endl;12 }13 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (14)

1 class coul2 {3 int couleur;4 public :5 coul (int cl)6 {7 cout << "Coul " << cl << endl;8 couleur = cl ;9 }

10 void affiche ()11 {12 cout << "Couleur : " << couleur << endl;13 }14 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (15)

1 class masse2 {3 int mas;4 public :5 masse (int m)6 {7 cout << "Masse " << m << endl;8 mas = m ;9 }

10 void affiche ()11 {12 cout << "Masse : " << mas << endl;13 }14 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (16)

1 class pointcoul : public virtual point, public coul2 {3 public :4 pointcoul (int abs, int ord, int cl) : point (abs,ord)

, coul (cl)5 {6 cout << "Pointcoul " << abs << " " << ord << " " <<

cl << endl ;7 }8 void affiche ()9 {

10 point::affiche () ; coul::affiche ();11 }12 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (17)

1 class pointmasse : public virtual point, public masse2 {3 public :4 pointmasse (int abs, int ord, int m) : point(abs,ord),

masse (m)5 {6 cout << "Pointmasse " << abs << " " << ord << " " <<

m << endl;7 }8 void affiche ()9 {

10 point::affiche (); masse::affiche ();11 }12 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (18)

1 class pointcolmasse : public pointcoul, public pointmasse2 {3 public :4 pointcolmasse (int abs, int ord, int c, int m) : point

(abs, ord), pointcoul (abs, ord, c), pointmasse (abs, ord, m)

5 {6 cout << "Pointcolmasse " << abs << " " << ord << " "

<< c << " " << m << endl;7 }8 void affiche ()9 {

10 point::affiche () ; coul::affiche() ; masse::affiche();

11 }12 };

Dr Bernard Ries LAMSADE LANGAGE C++

HERITAGE MULTIPLE (19)

1 main()2 {3 pointcoul p(3,9,2) ;4 p.affiche () ;5 pointmasse pm(12, 25, 100) ;6 pm.affiche () ;7 pointcolmasse pcm (2, 5, 10, 20) ;8 pcm.affiche () ;9 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS

1 class Rectangle2 {3 private:4 float m_hauteur;5 float m_largeur;6 public:7 Rectangle(float, float);8 float surface();9 };

1 main()2 {3 Rectangle R(3,4);4 cout << R ; // ERREUR!5 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS

1 class Rectangle2 {3 private:4 float m_hauteur;5 float m_largeur;6 public:7 Rectangle(float, float);8 float surface();9 };

1 main()2 {3 Rectangle R(3,4);4 cout << R ; // ERREUR!5 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (2)

Afin de pouvoir ecrire une ligne comme1 cout << R ;

il faudra surdefinir l’operateur << !

L’operateur << possede deux operandes dont le premier est unflot de sortie : cout.

Un flot de sortie est en fait un objet d’une classe predefinie, asavoir ostream.

Cette classe surdefinit l’operateur << pour les differents types debase sous la forme :

1 ostream& operator << (expression)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (2)

Afin de pouvoir ecrire une ligne comme1 cout << R ;

il faudra surdefinir l’operateur << !

L’operateur << possede deux operandes dont le premier est unflot de sortie : cout.

Un flot de sortie est en fait un objet d’une classe predefinie, asavoir ostream.

Cette classe surdefinit l’operateur << pour les differents types debase sous la forme :

1 ostream& operator << (expression)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (2)

Afin de pouvoir ecrire une ligne comme1 cout << R ;

il faudra surdefinir l’operateur << !

L’operateur << possede deux operandes dont le premier est unflot de sortie : cout.

Un flot de sortie est en fait un objet d’une classe predefinie, asavoir ostream.

Cette classe surdefinit l’operateur << pour les differents types debase sous la forme :

1 ostream& operator << (expression)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (2)

Afin de pouvoir ecrire une ligne comme1 cout << R ;

il faudra surdefinir l’operateur << !

L’operateur << possede deux operandes dont le premier est unflot de sortie : cout.

Un flot de sortie est en fait un objet d’une classe predefinie, asavoir ostream.

Cette classe surdefinit l’operateur << pour les differents types debase sous la forme :

1 ostream& operator << (expression)2 {3 ...4 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (3)

Il y a deux operandes :

1 la classe l’ayant appelee ;2 une expression d’un type de base quelqconque.

L’operateur << peut etre redefini par l’utilisateur pour des typesclasse qu’il a lui-meme crees.

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (3)

Il y a deux operandes :

1 la classe l’ayant appelee ;2 une expression d’un type de base quelqconque.

L’operateur << peut etre redefini par l’utilisateur pour des typesclasse qu’il a lui-meme crees.

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (4)

Pour ce faire, il suffit de tenir compte des points suivants :

l’operateur << doit recevoir un flot en premier argument,ce qui empeche de le surdefinir sous la forme d’une methodede la classe concernee ; il s’agira donc obligatoirement d’unefonction independante ou amie de la classe concernee ;la valeur de retour sera obligatoirement la reference auflot concerne (recu en premier argument).

Ainsi le prototype sera de la forme :1 ostream& operator << (ostream& , type_classe);

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (4)

Pour ce faire, il suffit de tenir compte des points suivants :l’operateur << doit recevoir un flot en premier argument,ce qui empeche de le surdefinir sous la forme d’une methodede la classe concernee ; il s’agira donc obligatoirement d’unefonction independante ou amie de la classe concernee ;

la valeur de retour sera obligatoirement la reference auflot concerne (recu en premier argument).

Ainsi le prototype sera de la forme :1 ostream& operator << (ostream& , type_classe);

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (4)

Pour ce faire, il suffit de tenir compte des points suivants :l’operateur << doit recevoir un flot en premier argument,ce qui empeche de le surdefinir sous la forme d’une methodede la classe concernee ; il s’agira donc obligatoirement d’unefonction independante ou amie de la classe concernee ;la valeur de retour sera obligatoirement la reference auflot concerne (recu en premier argument).

Ainsi le prototype sera de la forme :1 ostream& operator << (ostream& , type_classe);

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (4)

Pour ce faire, il suffit de tenir compte des points suivants :l’operateur << doit recevoir un flot en premier argument,ce qui empeche de le surdefinir sous la forme d’une methodede la classe concernee ; il s’agira donc obligatoirement d’unefonction independante ou amie de la classe concernee ;la valeur de retour sera obligatoirement la reference auflot concerne (recu en premier argument).

Ainsi le prototype sera de la forme :1 ostream& operator << (ostream& , type_classe);

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (5)

1 class Rectangle2 {3 private:4 float m_hauteur;5 float m_largeur;6 public:7 Rectangle(float, float);8 float surface();9 friend ostream& operator << (ostream&, Rectangle);

10 };11 ostream& operator << (ostream& sortie, Rectangle R)12 {13 sortie << "Hauteur: " << R.m_hauteur << endl;14 sortie << "Largeur: " << R.m_largeur << endl;15 sortie << "Surface: " << R.surface() << endl;16 return sortie;17 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (6)

ExerciceSurcharger l’operateur << pour la classe Vect suivante :

1 class Vect2 {3 private:4 int m_taille;5 int* m_tab;6 public:7 Vect(int n)8 {9 m_taille=n;

10 m_tab=new int[m_taille];11 for (int i=0; i<m_taille; i++)12 {13 m_tab[i]=m_taille-i;14 }15 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (7)

1

2 ˜Vect()3 {4 delete [] m_tab;5 }6 };

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (8)

1 class Vect2 {3 private:4 int m_taille;5 int* m_tab;6 public:7 Vect(int n)8 {9 m_taille=n;

10 m_tab=new int[m_taille];11 for (int i=0; i<m_taille; i++)12 {13 m_tab[i]=m_taille-i;14 }15 }

Dr Bernard Ries LAMSADE LANGAGE C++

LES FLOTS (9)

1 ˜Vect()2 {3 delete [] m_tab;4 }5 friend ostream& operator << (ostream&, Vect);6 };7

8 ostream& operator << (ostream& sortie, Vect v)9 {

10 sortie << "Taille du vecteur: " << v.m_taille << endl;11 for (int i=0; i<v.m_taille; i++)12 {13 sortie << v.m_tab[i] << " ";14 }15 sortie << endl;16 return sortie;17 }

Dr Bernard Ries LAMSADE LANGAGE C++

Recommended