Sunteți pe pagina 1din 8

O en est-on?

Nous connaissons maintenant les aspects


essentiels de la POO :
Encapsulation et abstraction
regroupement traitements et donnes :
class Rectangle { ... };
sparation entre interface et dtails
dimplmentation :
public, protected, private
Hritage : relation est-un
class Guerrier : public Personnage {...};
Polymorphisme
pouvoir tre vu de plusieurs faons,
abstraction, gnricit
2 ingrdients ncessaires : pointeurs
et mthodes virtuelles
classes abstraites et mthodes
virtuelles pures
Quest-ce que lhritage multiple ?
En C++, une sous-classe peut hriter de plusieurs super-classes :
Classe A Classe B
Classe C
Comme pour lhritage simple, la sous-classe hrite des super-classes :
tous leurs attributs et mthodes (sauf les constructeurs/destructeurs)
leur type
Encore un jeu . . .
Supposons que lon souhaite programmer
un jeu mettant en scne les entits
suivantes :
1. Balle
2. Raquette
3. Filet
4. Joueur
Chaque entit sera principalement dote
dune mthode evolue, grant lvolution
de lentit dans le jeu.
Premire bauche de conception (1)
class Entite
void evolue(...)
class Balle class Raquette class Filet class Joueur
Premire bauche de conception (2)
Si lon analyse de plus prs les besoins du jeu, on ralise que :
certaines entits doivent avoir une reprsentation graphique
(Balle, Raquette, Filet)
. . . et dautres non (Joueur)
certaines entits doivent tre interactives
(on veut par exemple pouvoir les contrler avec la souris) :
Balle, Raquette
. . . et dautres non : Joueur, Filet

Comment organiser tout cela ?


Jeu vido impossible
Il nous faudrait mettre en place une hirarchie de classes telle que celle-ci :
class Balle class Raquette class Filet class Joueur
void evolue(...)
class Entite class Interactif
void gestionClic()
class Graphique
void dessiner()

Possible en C++ grce lhritage multiple!


Autre exemple
Un exemple zoologique :
Vivipare Ovipare
Ovovivipare
Encore un exemple
... informatique :
ios
ostream
iostream ifstream ofstream
fstream
istream
Hritage multiple
Syntaxe :
class nomSousClasse: public nomSuperClasse1, ...
public nomSuperClasseN {
//...
};
Exemple :
class Ovovivipare: public Ovipare, public Vivipare {
public:
Ovovivipare(unsigned int, unsigned int);
virtual ~Ovovivipare();
protected:
bool espece_rare;
};
Lordre de dclaration des super-classes est pris en compte lors de linvocation des
constructeurs/destructeurs
Constructeurs/destructeurs
Comme pour lhritage simple, linitialisation
des attributs hrits doit tre faite par invocation
des constructeurs des super-classes :
Syntaxe :
SousClasse(liste de paramtres)
: SuperClasse1(arguments1),
...
SuperClasseN(argumentsN),
attribut1(valeur1),
...
attributK(valeurK)
{}
Lorsque lune des super-classes admet un constructeur par dfaut,
il nest pas ncessaire de linvoquer explicitement.
Constructeurs/destructeurs (2)
Attention ! Lexcution des constructeurs
des super-classes se fait selon lordre de
la dclaration dhritage, et non selon
lordre des appels dans le constructeur !
Lordre des appels des destructeurs de
super-classes est linverse de celui des
appels de constructeurs
Constructeurs/destructeurs : exemple
class Ovovivipare : public Ovipare, public Vivipare {
public:
Ovovivipare(unsigned int nb_oeufs ,
unsigned int duree_gestation ,
bool rarete = false );
virtual ~Ovovivipare();
protected:
bool espece_rare;
};
Ovovivipare::Ovovivipare(unsigned int nb_oeufs ,
unsigned int duree_gestation ,
bool rarete)
: Vivipare(duree_gestation), // Mauvais ordre !!
Ovipare(nb_oeufs),
espece_rare(rarete)
{}
Accs direct ambigu
Comme dans le cas de lhritage simple, une sous-classe peut accder directement
aux attributs et mthodes protgs de ses super-classes.
... et si ces attributs/mthodes portent le mme nom
dans plusieurs super-classes ?
class Ovipare {
// ...
void afficher() const;
};
class Vivipare {
// ...
void afficher() const;
};
class Ovovivipare : public Ovipare,
public Vivipare
{ //...
};
int main()
{
Ovovivipare o(...);
o.afficher();
return 0;
}
Accs direct ambigu (2)
Attention ! Laccs o.afficher provoquera une erreur la compilation mme si la
mthode afficher navait pas les mmes paramtres dans les deux classes
Ovipare et Vivipare !!!
(La raison est quen C++, il ny a surcharge que dans la mme porte. Ici ce nest pas une
problme de surcharge, mais un problme de masquage [rsolution de porte].)
class Ovipare {
// ...
void afficher() const;
};
class Vivipare {
// ...
void afficher(string const& entete) const;
};
class Ovovivipare : public Ovipare,
public Vivipare
{ //...
};
int main()
{
Ovovivipare o(...);
o.afficher("Un orvet : ");
return 0;
}
Accs direct ambigu solutions ?
Solutions ?
Premire solution : utiliser loprateur de rsolution de porte.
int main()
{
Ovovivipare o(...);
o.Vivipare::afficher("Un orvet : ");
return 0;
}
mais...
Accs direct ambigu critique de la solution 1
mais...
Lutilisation (externe) de loprateur de
rsolution de porte pour rsoudre
les ambiguts de noms des attri-
buts/mthodes nest pas une bonne
solution :
Cest lutilisateur de la classe Ovovivipare
qui dcide du fonctionnement correct de
cette classe,
alors que cette responsabilit doit norma-
lement incomber aux concepteurs de la
classe.
Accs direct ambigu solution 2
Une des solutions consiste lever lambigut en indiquant explicitement dans la
sous-classe quelle(s) mthode(s) on veut invoquer :

ajouter la sous-classe, une dclaration spciale indiquant quel(s)


mthode(s)/attribut(s) seront invoqu(s) exactement.
Syntaxe : using NomSuperClasse::NomAttributOuMethodeAmbigu ;
Exemple :
class Ovovivipare : public Ovipare, public Vivipare {
public:
using Vivipare::afficher;
// ...
};
Attention ! Pas de parenthse (ni prototype) derrire le nom de la mthode!
Accs direct ambigu solution 3
La meilleure solution consiste ajouter dans la sous-classe une mthode
dnissant la bonne interprtation de linvocation ambigu.
Exemple :
class Ovovivipare: public Ovipare, public Vivipare {
public:
// ...
void afficher() const {
Ovipare::afficher();
Vivipare::afficher(" mais aussi pour sa partie"
" vivipare : ");
}
// ...
};
Classes virtuelles : problme
Il peut se produire quune super-classe soit incluse plusieurs fois dans une
hirarchie hritage multiple :
Vivipare Ovipare
Ovovivipare
Animal Animal
ios
ostream
iostream ifstream ofstream
fstream
istream
Les attributs/mthodes de la super-classe seront inclus plusieurs fois !

Chaque objet de la classe Ovovivipare possdera deux copies


des attributs de la classe Animal.
Classes virtuelles : exemple du problme
class Animal {
public: Animal(string const& description) : tete(description) {}
protected: string tete;
};
class Ovipare : public Animal { public: Ovipare() : Animal(" cornes") {} };
class Vivipare : public Animal { public: Vivipare() : Animal("de poisson") {} };
class Ovovivipare : public Ovipare, public Vivipare {
public:
void affiche() const { cout << "j'ai une tte " << Ovipare::tete
<< " et une tte " << Vivipare::tete << " !" << endl;
}
};
// ...
Ovovivipare x;
x.affiche();

jai une tte cornes et une tte de poisson !


Classes virtuelles solution
Pour viter la duplication des attributs dune super-classe plusieurs fois incluse lors
dhritages multiples, il faut dclarer son lien dhritage avec toutes ses
sous-classes comme virtuel.
Cette super-classe sera alors dite virtuelle
( ne pas confondre avec classe abstraite !!)
Syntaxe :
class NomSousClasse : public virtual NomSuperClasseVirtuelle
Exemple :
class Ovipare : public virtual Animal { // ...
// ...
class Vivipare: public virtual Animal { // ...
A noter que cest la classe pouvant tre hrite plusieurs fois qui est virtuelle (i.e. ici la
super-super-classe) et non pas directement les classes utilises dans lhritage multiple
(i.e. les super-classes).
Classes virtuelles (3)
Vivipare Ovipare
Ovovivipare
Animal
Un seul objet de la super-classe Animal est hrit par lhritage commun des
sous-classes Ovipare et Vivipare.
Constructeurs et Classes virtuelles
Rappel : dans un hritage usuel, le
constructeur dune sous-classe ne fait ap-
pel quaux constructeurs de ses super-
classes immdiates (et ceci rcursive-
ment)
Dans une drivation virtuelle, la super-
classe virtuelle est initialise directe-
ment par la sous(-sous-...)-classe ins-
tancie

Toutes ses sous(-sous-...)-classes


instanciables (= non-abstraites)
doivent donc faire directement
appel au constructeur de la
super(-super-...)-classe virtuelle
Constructeurs et Classes virtuelles : Exemple
Ovovivipare::Ovovivipare(string nom, Habitat habitat, Regime regime,
unsigned int nb_oeufs,
unsigned int gestation,
bool rarete = false)
: Animal(nom, habitat, regime),
Ovipare(nb_oeufs),
Vivipare(gestation),
espece_rare(rarete)
{}
Classes virtuelles : appel des constructeurs
Comment sont grs les appels au constructeur de la super-classe virtuelle?
Ovovivipare::Ovovivipare(// ...
)
: Animal(nom, habitat, regime),
Ovipare(nb_oeufs),
Vivipare(gestation),
espece_rare(rarete)
{}
Vivipare Ovipare
Ovovivipare
Animal
Ovovivipare o(...);
Classes virtuelles : appel des constructeurs
Lors de la cration dun objet dune classe plus drive, son constructeur invoque
directement le constructeur de la super-classe virtuelle.
Les appels au constructeur de la super-classe virtuelle dans les classes
intermdiaires sont ignors.
Si la super-classe virtuelle a un constructeur par dfaut, il nest pas ncessaire de
faire appel ce constructeur explicitement. Il sera directement appel par le
constructeur de la classe dont on cre une instance.
Sil ny a pas dappel explicite au constructeur de la super-classe virtuelle et si
celle-ci na pas de constructeur par dfaut, la compilation signalera une erreur.
Ordre des constructeurs/destructeurs
Dans une hirarchie de classes o il existe des super-classes virtuelles :
le soin dinitialiser les super-classes virtuelles incombe la sous-classe la plus
drive
les constructeurs des super-classes virtuelles sont invoqus en premier
les appels explicites au constructeur de la super-classe virtuelle dans les
classes intermdiaires sont ignors.
ceux des classes non-virtuelles le sont ensuite dans lordre de dclaration de
lhritage
lordre dappel des constructeurs de copie est identique
lordre dappel des destructeurs est linverse de celui des appels de
constructeurs

S-ar putea să vă placă și