Vous êtes sur la page 1sur 4

10.

L’héritage multiple

class A { ... } ; A B
class B { ... } ;
class C : public A, public B { ... } ;
C
FFigure 1

10.1 Conflit de noms

class A { public : affiche () ; ... } ;


class B { public : affiche () ; ... } ;
class HM : public A, public B { ... } ;

int main()
{
HM hm;
hm.affiche() // erreur de compilation car ambigu.
}

Ecrire hm.A::affiche() ou hm.B::affiche()


sinon redéfinir HM::affiche()

HM::affiche()
{
A :: affiche() ; // et / ou B :: affiche() ;
}

A A
10.2 Héritage 2 fois de la même classe
B C

HM

Figure 2
class A { protected : int k ; ... } ;
class B : public A { ... } ;
class C : public A { ... } ;
class HM : public B, public C { ... } ; // hérite 2 fois de k venant de A

void HM :: affiche()
{
cout << k; // ambigu, quel k ?

Page 1 sur 4
}

Pour éviter la duplication

class A { protected : int k ; ... } ;


class B : public A virtual { ... } ; // ou public virtual A !
class C : public A virtual { ... } ;
class HM : public virtual A, public B, public C { ... } ;
// hérite 1 seule fois de k venant de A

void HM :: affiche()
{
cout << k; // ok
}
A

B C

HM
Figure 3
A est déclaré classe de base virtuelle. Les éléments de la classe de base virtuelle ne sont
insérés qu’une seule fois dans la classe dérivée.

10.3 Appels des constructeurs.


Les constructeurs sont appelés dans l’ordre où ils sont mentionnés dans la déclaration de
la classe dérivée (Pas dans l’ordre où ils apparaissent dans le constructeur).

Et les constructeurs des classes de base virtuelles sont appelés avant les constructeurs des
classes de bases non virtuelles, enfin le constructeur de la classe dérivée.

Ordre d’appel des constructeurs de la classe HM

HM :: HM( .... ) : B ( ... ) , C ( ... ), A ( ... ) { ... } ; // constructeur de HM


Classe de base
constructeur de A virtuelle
constructeur de B
constructeur de C
constructeur de HM

10.4 Une utilisation :


Pour implémenter un type abstrait de données à partir d'une structure de données
fondamentales.

Page 2 sur 4
Type abstrait de Structure de données
données fondamentales

Pile abstraite Tableau


File abstraite Liste chaînée
Ensemble abstrait Arbre
... ...

Pile
File
Ensemble

Figure 4
Le type abstrait de données ne contient que des des fonctions membres virtuelles pures.
Qui sont implémentées dans la classe dérivée à l'aide d'une structure de données
fondamentales.

Class EnsembleAbstrait {
public :
virtual void ajouter( int ) = 0 ;
virtual void enlever ( int ) = 0 ;
virtual void contient ( int ) = 0 ;
};

Class Tableau {
....
};

Class Ensemble : public EnsembleAbstrait, private Tableau {


public :
virtual void ajouter( int ) { }
virtual void enlever ( int ) { }
virtual void contient ( int ) { }
};

Par héritage multiple de EnsembleAbstrait et Tableau ou


ou par héritage multiple de EnsembleAbstrait et Liste chaînée on fabrique une nouvelle
classe qui gère un ensemble d'entier

soit la fonction f :
void f (EnsembleAbstrait &e )
{
e.ajouter() ;
e.enlever() ;
...
}

cette fonction est indépendante de l'implémentation de la classe EnsembleAbstrait.

Page 3 sur 4
10.5 En conclusion

L’héritage multiple est plaisant d’un point de vue conceptuel, mais pose d’énormes
problèmes de maintenance et de conflit.

Page 4 sur 4

Vous aimerez peut-être aussi