Cours l’héritage multiple, tutoriel & guide de travaux pratiques en pdf.
Utilisation
L’héritage multiple est un sujet de controverses multiples. Beaucoup affirment qu’il s’agit là d’une possibilité à ne pas utiliser. La librairie standard d’entrées-sorties de C++, iostream.h, utilise l’héritage multiple pour dériver iostream de istream et de ostream, pour exprimer par là la fait que iostream est à la fois un flot d’entrée (istream) et un flot de sortie (ostream).
L’exemple suivant illustre de manière simple un cas d’héritage multiple. Cet exemple est artificiel et n’illustre que la manière d’utiliser l’outil. #include <iostream.h>
class A { int anInt; public : A(int a) anInt(a) {} void aFunc() { cout<<« aFunc Called »<<endl; } };
class B { int anInt; public : B(int b) anInt(b) {} void bFunc() { cout<<« bFunc Called »<<endl: } }; class D : public A, public B { int anInt; public : D(int d, int b, int a) : A(a), B(b), anInt(d) {} void dFunc() { cout<<« cFunc called »<<endl; };
void main()
{ D d(10, 20, 30); d.bFunc(); d.aFunc(); d.dFunc(); }
Dans l’exemple çi-dessus, la classe D hérite publiquement de A et de B. On exprime par là, comme dans le cas de l’héritage simple, que D est un (isa) A et un B. Il est possible, dans le cas de l’héritage multiple, de spécifier, pour chaque branche d’héritage et de manière indépendante, le type d’héritage souhaité. Par défaut, le type d’héritage est privé. Ainsi, la déclaration suivante exprimerait le fait que D dérive publiquement de A, mais de manière privée de B :
class D: public A, private B {…}
Le langage C++ 247
einev Télécommunications mjn
Cette formulation est équivalente à :
class D: public A, B { … }
Ambiguïtés d’identificateurs
L’exemple ci-dessus illustre un cas idéal. main() peut utiliser les diverses méthodes sans introduire le moindre risque d’ambiguités. Ceci est possible parceque les divers identificateurs sont parfaitement univoques. Il n’en va pas de même dans l’exemple çi-dessous:
class A { int anInt; public : A(int a) anInt(a) {} void someFunc() { cout<<« someFunc(A) Called »<<endl; } };
class B { int anInt; public : B(int b) anInt(b) {} void someFunc() { cout<<« someFunc(B) Called »<<endl: } }; class D : public A, public B { int anInt; public : D(int d, int b, int a) : A(a), B(b), anInt(d) {} void dFunc() { cout<<« dFunc called »<<endl; };
void main()
{ D d(10, 20, 30); d.bFunc(); d.A::someFunc(); d.B::someFunc(); // someFunc ne permet pas de dire laquelle des // deux fonctions doit être appelée. Il faut donc // spécifier le chemin d’accès complètement.