Vous êtes sur la page 1sur 9

Centre Informatique pour les Lettres

et les Sciences Humaines


Apprendre C++ avec Qt : Leon 13
Classes drives






1 - Notion de spcialisation ...................................................................................................... 2
2 - Le mcanisme de drivation ................................................................................................ 3
Cration d'une classe drive...........................................................................................3
Ce que l'hritage ne transmet pas....................................................................................4
Construction et destruction d'une instance d'une classe drive......................................4
Initialisation des membres hrits ...................................................................................4
Rgles d'accs aux membres hrits publiquement..........................................................5
Le cas des membres statiques .........................................................................................6
Ce que la drivation rend possible ...................................................................................6
Ce que la drivation ne suffit pas rendre possible .........................................................7
3 - Hirarchies de classes......................................................................................................... 7
4 - Drivation multiple ............................................................................................................. 7
5 - Drivation protge et drivation prive............................................................................... 8
6 - Bon, c'est gentil tout a, mais a fait dj 8 pages. Qu'est-ce que je dois vraiment en
retenir ?.............................................................................................................................. 9
Document du 20/01/06 - Retrouvez la version la plus rcente sur http://www.up.univ-mrs.fr/wcpp
C++ - Leon 13 Classes drives 2/9
Jusqu' prsent, les rapports liant les diffrentes classes que nous avons tudies se limitent
deux cas de figure : une classe peut en accepter une autre comme amie, et elle peut comporter
un membre qui est une instance d'une autre classe. Le processus de drivation, qui est l'objet de
cette Leon et de la prochaine, cre entre les classes un lien d'une toute autre nature.
1 - Notion de spcialisation
Il arrive que des types diffrents possdent des caractristiques communes qui justifient que
certains traitements soient appliqus des objets en ignorant duquel de ces types ces objets
sont des instanciations.

Imaginons, par exemple, que nous cherchions grer une entreprise de location de vhicules.
Cette entreprise possde une flotte qui comporte toutes sortes de vhicules et, notamment, des
camions et des voitures. Ces deux types de vhicules sont dcrits par des classes diffrentes,
parce que leurs caractristiques pertinentes pour notre programme sont trs diffrentes : les
voitures sont dcrites en termes de catgorie tarifaire, type de carburant utilis, quipements
disponibles, alors que les camions sont dcrits en termes de catgorie de permis de conduire
exig, volume de chargement, poids du chargement autoris, etc... Lors de certaines oprations,
notre programme est cependant amen parcourir l'ensemble des vhicules sans s'intresser
la distinction entre voitures et camions. Un exemple de traitement de ce genre pourrait tre le
calcul de la valeur totale de la flotte, par addition des valeurs estimes de chacun des vhicules.

Bien entendu, pour qu'un tel traitement soit concevable, il ne doit faire appel qu' des
caractristiques qui sont communes tous les types concerns.

On ne pourra pas, par exemple, faire le calcul de la moyenne des poids de chargement autoriss
par les vhicules de la flotte si cette donne n'est disponible que pour les camions. La valeur
estime est, par contre, sans doute disponible pour tous les types de vhicules.

Pour pouvoir manipuler de faon indiffrencie des objets de types diffrents, il faut trouver
ces types une dsignation commune. L'approche adopte par C++ est de considrer que les
caractristiques communes constituent une classe de base, qui peut tre utilise pour dfinir
des classes publiquement drives, qui sont autant de spcialisations de la classe de base.

Dans notre exemple, nous serions donc conduits concevoir une classe de base (que nous
pourrions nommer CVehi cul e ) et qui dfinirait les aspects communs tous les types de
vhicules (la valeur estime, notamment). Des classes telles que CVoi t ur e et CCami on peuvent
tre drives de CVehi cul e, ce qui permet de leur confrer les caractristiques qui leur sont
propres, tout en garantissant qu'elles prsentent exactement les caractristiques qui doivent leur
tre communes.

La proprit essentielle du processus de drivation est que

Les instances d'une classe drive publiquement sont aussi des instances de la classe de base.

En d'autres termes, nos CVoi t ur e (tout comme nos CCami on) seront des CVehi cul e...

Cette proprit est essentielle car, grce elle, il est possible de stocker, dans un pointeur
destin recevoir l'adresse d'une instance de la classe de base, l'adresse d'une instance de
l'une des classes drives. Un tel pointeur permet donc de traiter un ensemble d'objets de types
diffrents, en ne s'intressant qu'aux aspects communs tous ces types.

Dans notre exemple, le mme pointeur sur CVehi cul e pourra donc contenir certains moments
l'adresse d'un CCami on, d'autres l'adresse d'une CVoi t ur e, ou celle d'une instance de
n'importe laquelle des classes drives (publiquement) de CVehi cul e. Ce pointeur peut donc tre
utilis pour parcourir l'intgralit de la flotte et faire, par exemple, la somme des valeurs
estimes des vhicules.

Il s'agit l de la vritable raison d'tre du processus de drivation de classes, au point que,
dans le langage courant,

Lorsqu'on dit simplement d'une classe qu'elle est drive d'une autre, on veut dire qu'elle en
drive publiquement.

Il existe galement deux autres formes de drivation (protge et prive), mais leur usage est
beaucoup plus exceptionnel, et elles ne feront ici l'objet que d'une prsentation succincte.
J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 3/9
2 - Le mcanisme de drivation
Le principe fondamental de la drivation est que la classe drive comporte implicitement tous
les membres dfinis dans la classe de base. Cette transmission est gnralement connue sous
le nom d'hritage, et l'on dit donc couramment que la classe drive hrite des membres dfinis
dans la classe de base.

Le terme "hritage" est particulirement heureux, mais son succs mondain conduit
malheureusement souvent des contresens quant la nature profonde du processus de
drivation, qui n'est pas un simple moyen de transfuser du code d'une classe vers une autre
pour viter d'avoir le rcrire.

Pour simplifier la discussion, admettons que nous disposons d'une classe ainsi dfinie :

cl ass CVehi cul e 1
{ 2
publ i c: 3
CVehi cul e( doubl e val eur I ni t i al e = 0) : ar gus( val eur I ni t i al e) {} 4
doubl e val eur Est i mee( ) const {r et ur n ar gus; } 5
voi d val eur Est i mee( doubl e nouvel l e) {ar gus = nouvel l e; } 6
pr ot ect ed: 7
doubl e ar gus; 8
}; 9
Cration d'une classe drive
La cration d'une classe drive exige que le nom de la classe cre soit suivi de deux points,
de la spcification du type de drivation souhaite et du nom de la classe de base devant tre
utilise :

cl ass CVoi t ur e : publ i c CVehi cul e / / l es CVoi t ur e SONT des CVehi cul e 1
{ 2
}; 3

Bien que la dfinition de cette classe soit ostensiblement vide, toute instance de CVoi t ur e
possde une variable membre nomme argus et deux fonctions membre nommes
val eur Est i mee( ) . La classe CVoi t ur e permet donc dj d'crire des choses comme

CVoi t ur e t i t i ne; / / cr at i on d' une i nst ance 1
t i t i ne. val eur Est i mee( 1000) ; / / modi f i cat i on de sa val eur 2
doubl e pr i x = t i t i ne. val eur Est i mee( ) ; / / ut i l i sat i on de sa val eur 3

Bien entendu, si la classe drive ne comporte aucune caractristique supplmentaire par
rapport la classe de base, elle ne prsente aucun intrt. Les caractristiques
supplmentaires en question sont ajoutes en dclarant des membres propres la classe
CVoi t ur e, qui viennent simplement s'ajouter aux membres hrits de CVehi cul e :

enumE_CATEGORI E {COMPACTE, MOYENNE, FAMI LI ALE, LUXE, CAT_I NCONNUE}; 1
enumE_CARBURANT {ESSENCE, GAZOLE, ELECTRI CI TE, CARB_I NCONNU}; 2
enumE_BOI TE_VI TESSE {AUTO, MANUELLE, BOI TE_I NCONNUE}; 3

cl ass CVoi t ur e : publ i c CVehi cul e / / l es CVoi t ur e SONT des CVehi cul e 4
{ 5
publ i c: 6
doubl e pr i xLocat i on( ) ; 7
pr ot ect ed: 8
E_CATEGORI E cat egor i e; 9
E_CARBURANT car bur ant ; 10
E_BOI TE_VI TESSE bv; 11
}; 12

La faon dont la fonction CVoi t ur e: : pr i xLocat i on( ) dtermine la valeur qu'elle renvoie est
sans grand intrt dans le cas prsent. Imaginons simplement que cette fonction effectue un
calcul o interviennent les caractristiques de l'instance au titre de laquelle elle est appele.
J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 4/9
Ce que l'hritage ne transmet pas
Les constructeurs, le destructeur et les fonctions dfinissant l'oprateur d'affectation ne sont
jamais hrits.

La raison de ces exceptions est assez vidente : tant donn qu'une classe drive peut
comporter des variables membre qui n'existent pas dans la classe de base, un constructeur de
la classe de base ne peut pas initialiser compltement une instance d'une classe drive. Le
mme argument vaut pour le destructeur et les oprateurs d'affectation de la classe de base,
qui ne sauraient traiter correctement des membres qui sont propres une classe drive et
dont ils ignorent ncessairement tout.

Les relations d'amiti ne sont pas non plus transmises par hritage. Si une classe drive doit
accepter comme amie une classe (ou une fonction), elle doit exprimer elle-mme cette
acceptation, mme si la classe (ou la fonction) en question est dj amie de la classe de base.
Construction et destruction d'une instance d'une classe drive
L'instanciation d'une classe drive implique ncessairement l'excution d'un constructeur de
la classe de base (qui initialise les membres hrits), puis celle d'un constructeur de la classe
drive (qui initialise les membres propres celle-ci).

Symtriquement, lors de la disparition d'une instance d'une classe drive, l'excution du
destructeur de cette classe (qui "fait le mnage" dans les membres propres cette classe)
s'accompagne automatiquement d'un appel au destructeur de la classe de base (qui "fait le
mnage" dans les membres hrits).

Si vous dfinissez explicitement le destructeur d'une classe drive, aucun appel au destructeur
de la classe de base ne doit y figurer. L'excution de ce destructeur est rendue indispensable
dans ce contexte par la relation d'hritage liant les deux classes, et le langage assure qu'il sera
implicitement invoqu au moment judicieux.
Initialisation des membres hrits
Dans notre exemple, la classe CVehi cul e dfinit un constructeur qui accepte un paramtre
permettant d'initialiser la valeur estime du vhicule. On peut donc crire

CVehi cul e unVehi cul e( 10000) ; / / on peut cr er des CVehi cul e d' une val eur quel conque

La classe CVoi t ur e, par contre, ne dfinit explicitement aucun constructeur. Comme les
constructeurs ne sont pas hritables, elle ne dispose que des constructeurs automatiquement
gnrs par le compilateur (c'est dire, au maximum, un constructeur par dfaut et un
constructeur par copie). Il n'est donc pas possible d'crire

CVoi t ur e bat mobi l e( 9999999) ; / / I MPOSSI BLE : l e const r uct eur r equi s n' exi st e pas !

Dans la version gnre automatiquement du constructeur par dfaut d'une classe drive, les
membres hrits sont initialiss par appel du constructeur par dfaut de la classe de base.

Nos CVoi t ur e ont donc une valeur estime initiale nulle.

Pour rendre possible l'initialisation avec une valeur arbitraire des instances des classes
drives de CVehi cul e, il faut pourvoir ces classes de constructeurs explicitement dfinis. La
liste d'initialisation permet alors de choisir quel constructeur de la classe de base va tre utilis
pour initialiser les membres hrits. Si nous ngligeons ses caractristiques spcifiques, la
classe CCami on pourrait, par exemple, procder ainsi :

cl ass CCami on : publ i c CVehi cul e 1
{ 2
publ i c: 3
CCami on( ) : CVehi cul e( 100) {} 4
}; 5

Dfinie de cette faon, la classe CCami on donne naissance des instances dont la valeur
estime initiale est de 100. Le constructeur de CCami on peut, bien entendu, tre lui-mme dot
d'un paramtre lui indiquant quelle valeur transmettre au constructeur de CVehi cul e :

J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 5/9
cl ass CCami on : publ i c CVehi cul e 1
{ 2
publ i c: 3
CCami on( doubl e val eur I ni t i al e = 0) : CVehi cul e( val eur I ni t i al e) {} 4
}; 5

Il devient alors possible de crer des CCami on d'une valeur initiale quelconque.
Rgles d'accs aux membres hrits publiquement
Pour une fonction membre d'une classe drive, la possibilit d'accder aux membres hrits
de la classe de base dpend des privilges d'accs associs ceux-ci.

S'il s'agit d'un membre public ou d'un membre protg de la classe de base, aucune restriction
n'est applique et les fonctions membre de la classe drive peuvent accder librement au
membre hrit.

Dans l'tat actuel de la classe CVehi cul e, la fonction CVoi t ur e: : pr i xLocat i on( ) , par
exemple, peut donc parfaitement utiliser la variable ar gus, bien que cette variable soit protge.

Remarquez que cette rgle ne s'applique que pour l'accs aux membres de l'instance au titre de
laquelle la fonction est excute. Pour les autres instances, une fonction membre propre la
classe drive n'aura accs aux membres hrits que s'ils sont publiques.

Si la fonction CVoi t ur e: : pr i xLocat i on( ) possde, par exemple, une variable locale de type
CVehi cul e, il lui reste interdit d'accder au membre argus de celle-ci, puisqu'il est protg.

Le langage C++ comporte un troisime rgime d'accs : lorsqu'un membre de la classe de base
est priv, seules les fonctions membres ou amies de la classe de base y ont accs.

En dehors du contexte des fonctions membre d'une classe drive, les membres protgs et
privs ont exactement les mmes proprits. C'est ce qui explique que nous n'avons pas
rencontr cette distinction au cours des Leons prcdentes.

Ceci ne signifie pas que la classe drive possde des membres auxquels aucune de ses
fonctions n'a accs. Les fonctions membre de la classe drive qui sont elles-mme hrites de
la classe de base ont en effet accs tous les membres hrits (puisque ces fonctions sont, par
dfinition, galement membre de la classe de base). La signification de la "privatisation" est
donc claire : la manipulation des membres concerns est du seul ressort des fonctions
membres dfinies au niveau de la classe de base, ce qui implique qu'elle sera la mme pour
toutes les classes drives.

Dans le cas de notre classe CVehi cul e, il serait donc sans doute prfrable d'crire :

cl ass CVehi cul e 1
{ 2
publ i c: 3
CVehi cul e( doubl e val eur I ni t i al e = 0) : ar gus( val eur I ni t i al e) {} 4
doubl e val eur Est i mee( ) const {r et ur n ar gus; } 5
voi d val eur Est i mee( doubl e nouvel l e) {ar gus = nouvel l e; } 6
pr i vat e: 7
doubl e ar gus; 8
}; 9

Cette modification du statut du membre argus a pour effet d'imposer galement aux membres
des classes drives de CVehi cul e la contrainte subie par le code qui se contente d'instancier
la classe : l'accs l'information n'est plus possible que via une fonction membre.

Imposer cette contrainte prsente toujours le mme intrt fondamental (cf. Leon 9), qui est
d'isoler efficacement la signification l'information (qui intresse le code utilisateur) de la faon
dont celle-ci est reprsente (qui ne concerne que le code dfinissant la classe). Dans le cas
d'une classe de base, choisir entre des membres protgs et des membres privs, c'est dcider
si l'on considre les classes drives comme du code utilisateur ou comme du code participant
la dfinition, non pas d'une classe, mais d'un ensemble de classes troitement lies. Etant
donn qu'une classe de base peut comporter la fois des membres protgs et des membres
privs, cette dcision peut, selon les besoins, tre nuance de faon trs fine.
J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 6/9
Le cas des membres statiques
Lorsqu'une classe de base comporte un membre statique (cf. Annexe 3), ce membre est
commun non seulement toutes les instances de la classe de base, mais aussi toutes les
classes drives de cette classe de base et leurs instances.

Si l'on souhaite, par exemple, doter notre systme de gestion de vhicules d'un dnombrement
automatique du nombre d'instances, il nous faut modifier la classe de base de faon
- dclarer (11) une variable statique prive qui servira de compteur d'occurrences ;
- dfinir (9) une fonction statique permettant au code utilisateur d'obtenir la valeur courante
de cette variable ;
- veiller (4 et 5) ce que tous les constructeurs incrmentent le compteur ;
- veiller ce que le destructeur dcrmente ce pointeur ;
- dfinir et initialiser zro (dans un fichier CVehicule.cpp ?) la variable CVehi cul e: : nb.

cl ass CVehi cul e 1
{ 2
publ i c: 3
CVehi cul e( doubl e val eur I ni t i al e = 0) : ar gus( val eur I ni t i al e) {++nb; } 4
CVehi cul e( const CVehi cul e & model e) : ar gus( model e. ar gus) {++nb; } 5
~CVehi cul e( ) {- - nb; } 6
doubl e val eur Est i mee( ) {r et ur n ar gus; } 7
voi d val eur Est i mee( doubl e nouvel l e) {ar gus = nouvel l e; } 8
st at i c i nt nbVehi cul es( ) {r et ur n nb; } 9
pr i vat e: 10
st at i c i nt nb; 11
doubl e ar gus; 12
}; 13

Aucune modification des classes drives n'est ncessaire.

Lorsque l'une de ces classes est instancie, les membres hrits sont initialiss par appel d'un
constructeur de la classe de base, ce qui assure l'incrmentation du compteur. Conformment
au principe selon lequel les instances de la classe drive sont aussi des instances de la classe
de base, la cration d'une CVoi t ur e se traduira donc par une augmentation du nombre de
CVehi cul e. De mme, la disparition d'une instance d'une classe drive s'accompagne
automatiquement d'une excution du destructeur de la classe de base, ce qui garantit
l'exactitude du dnombrement.

La fonction nbVehi cul es( ) peut tre appele de multiples faons :

CVehi cul e: : nbVehi cul es( ) ; / / appel au t i t r e de l a cl asse de base 1
CVoi t ur e: : nbVehi cul es( ) ; / / appel au t i t r e d' une cl asse dr i ve 2
CVehi cul e x; 3
x. nbVehi cul es( ) ; / / appel au t i t r e d' une i nst ance de l a cl asse de base 4
CVoi t ur e a; 5
a. nbVehi cul es( ) ; / / appel au t i t r e d' une i nst ance d' une cl asse dr i ve 6

Tous ces appels se rsolvant par l'excution de la mme fonction, il semble toutefois prfrable
de privilgier l'appel au titre de la classe de base, qui exprime clairement aussi bien le fait qu'il
s'agit d'une fonction statique que le fait qu'elle est dfinie dans la classe de base.
Ce que la drivation rend possible
La prise en compte explicite du fait que les camions comme les voitures (et, ventuellement,
d'autres types d'engins) sont des vhicules permet d'crire du code qui nglige les particularits
de ces objets. On peut, par exemple, crer une collection contenant les adresses de tous les
CVehi cul e de la flotte et dfinir des fonctions traitant cette collection :

doubl e val eur Tot al e( const QVal ueLi st < CVehi cul e * > & f l ot t e) 1
{ 2
doubl e t ot al = 0; 3
QVal ueLi st < CVehi cul e * >: : Const I t er at or i t ; 4
f or ( i t = f l ot t e. begi n( ) ; i t ! = f l ot t e. end( ) ; ++i t ) 5
t ot al += ( *i t ) - >val eur Est i mee( ) ; 6
r et ur n t ot al ; 7
} 8

J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 7/9
L'originalit profonde d'une telle fonction est qu'elle est parfaitement indiffrente la
composition de la flotte. Il est mme possible de crer de nouvelles classes drives de
CVehi cul e sans avoir reconsidrer le code qui n'accde aux objets que par l'intermdiaire
d'un pointeur (ou d'une rfrence) sur la classe de base.

Bien entendu, cette caractristique prsente un intrt pratique proportionnel la complexit
des traitements qui peuvent tre dfinis au niveau de la classe de base. Un exemple de quelques
lignes, tel que ceux envisageables dans une Leon, permet d'illustrer le fonctionnement de
l'hritage, mais certainement pas d'engranger un bnfice qui justifierait lui seul la complexit
de ce mcanisme. De ce point de vue, l'exemple propos dans le TD 12 est sans doute plus
convainquant, puisqu'il va s'agir d'hriter d'un ensemble de fonctions que nous ne serions tout
bonnement pas en mesure de mettre au point.
Ce que la drivation ne suffit pas rendre possible
La manipulation d'instances d'une classe drive au moyen d'un pointeur sur la classe de base
n'autorise l'accs qu'aux membres hrits. Il n'est en particulier pas possible d'appliquer une
collection htrogne telle que la f l ot t e de notre exemple prcdent un traitement qui ne
s'effectue pas exactement de la mme faon dans toutes les classes drives.

Dans l'tat actuel de nos connaissances, le traitement d'une collection htrogne ne peut faire
appel qu' du code dfini au niveau de la classe de base. Il faut donc non seulement que
l'opration envisage soit possible pour tous les types drivs, mais aussi qu'elle puisse tre
effectue par une seule et mme fonction.

Du point de vue de la gestion de collections htrognes, il faut aussi souligner qu'un
conteneur ne peut en aucun cas stocker des objets de types diffrents. Il serait illusoire de
crer un conteneur d'instances d'une classe de base et d'essayer ensuite d'y stocker des
instances de diffrentes classes drives : la copie d'une valeur de ce genre exige videmment la
prise en compte des variables propres la classe drive concerne, et le "moule" obtenu en
annonant une collection d'instances de la classe de base ne laisse aucune place ces
variables.

Le transfert d'une valeur d'un type driv dans une instance de la classe de base laisse de ct
les membres propres la classe drive.

C'est pour cette raison que, dans l'exemple prcdent, la collection htrogne est gre par une
liste de pointeurs sur CVehi cul e, et non par une liste de CVehi cul e.
3 - Hirarchies de classes
La notion de "classe de base" n'implique pas de caractristique spciale. D'un point de vue
syntaxique, n'importe quelle classe peut donc, a priori, servir de base la cration d'une classe
drive. Il est en particulier tout fait possible qu'une classe drive serve elle-mme de classe
de base une classe drive "de seconde gnration". On peut ainsi crer des hirarchies de
classes drivant les unes des autres.

Lorsqu'une classe drive d'une classe elle-mme drive, on se trouve dans une situation que
l'on peut dcrire comme des hritages successifs (ou un hritage indirect).

Aucune rgle de fonctionnement particulire ne dcoule du fait que la classe de base d'une
classe est elle-mme dj une classe drive. La seule vritable complexit introduite par ce
type de situation est celle inhrente la hirarchie cre : il est particulirement important de
procder une analyse pralable soigneuse et, notamment, de veiller ce que toutes les
relations de drivation correspondent effectivement une spcialisation progressive par ajout
de caractristiques supplmentaires.
4 - Drivation multiple
Une classe peut aussi driver simultanment de plusieurs classes de base.

On rserve habituellement l'expression "hritage multiple" cette situation o une mme classe
a plusieurs "anctres" directs, par opposition celle cre par des hritages successifs (qui, d'un
certain point de vue, pourrait galement mriter cette appellation).

J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 8/9
Si notre entreprise de location diversifie son activit, nous pourrions tre amens crer la
classe CHabi t at i on, en vue de dcrire les maisons et appartements proposs (surface
habitable, quipements disponibles, etc). Il n'est pas impossible d'imaginer que le cas des
"mobile homes" pourrait alors tre trait par une classe hritant certains de ses membres de
CVehi cul e et d'autres de CHabi t at i on.

La cration d'une classe bnficiant de plusieurs hritages simultans n'implique aucun effort
syntaxique remarquable, puisqu'il s'agit simplement d'numrer les classes de base :

cl ass CMobi l eHome : publ i c CVehi cul e, publ i c CHabi t at i on 1
{ 2

}; 3

En toute honntet, si cet exemple suggre bien l'ide gnrale d'une situation d'hritage
multiple, je doute qu'il puisse tre rellement utilis dans un programme. Concevoir les "mobile
homes" comme une spcialisation du cas "habitation" risque en effet de nous conduire retirer
tellement de caractristiques de cette classe qu'elle cessera de prsenter le moindre intrt (un
"mobile home" est dpourvu d'adresse postale, par exemple).

La mise au point de hirarchies de classes utilisant l'hritage multiple peut s'avrer un
problme redoutable, aussi bien pour des raisons conceptuelles (cohrence de la modlisation
ralise) que pour des raisons purement techniques (les interactions entre les diffrents
aspects du langage peuvent devenir complexes).

L'utilisation de librairies commerciales reposant sur de telles hirarchies, en revanche, peut
offrir un rapport difficult/efficacit trs attrayant, mme pour un programmeur relativement
dbutant. Une fois les difficults d'analyse et d'implmentation rsolues (par des professionnels
de la question), l'hritage multiple permet en effet de "piocher" assez facilement dans un
ensemble de caractristiques disponibles.

La librairie Qt est un exemple de produit permettant cette approche.
5 - Drivation protge et drivation prive
Outre la drivation publique dont nous avons discut jusqu' prsent, le langage C++ propose
deux autres type d'hritages, qui sont obtenus au prix d'une variation syntaxique trs mineure.
Les mots pr ot ect ed: et pr i vat e: peuvent en effet remplacer publ i c: dans la dclaration de
"filiation" d'une classe :

cl ass CDer i vee : pr i vat e CBase / / hr i t age pr i v 1
{ 2
3
}; 4

Les droits d'accs aux membres sont alors diffrents de ceux prsents prcdemment :

- dans le cas d'un hritage protg, les membres qui sont dclars public: dans la classe de
base deviennent protgs dans la classe drive (les membres protgs et privs de la classe
de base gardent leur statut dans la classe drive) ;

- dans le cas d'un hritage priv, tous les membres de la classe de base deviennent des
membres privs de la classe drive.

Ces rgles dfinissent le cas "normal". Les membres de la classe de base dont le contrle d'accs
est modifi par un hritage protg ou priv peuvent, par ailleurs, faire l'objet d'une redfinition
dans une classe drive, de faon leur restaurer leur statut initial...

La diffrence essentielle entre ces types de drivation et la drivation publique ne rside
cependant pas l, mais dans le fait que

Les instances d'une classe drive de faon protge (ou prive) d'une classe de base NE SONT
PAS des instances de la classe de base.

Ces types de drivation ne correspondent donc pas la notion de spcialisation dfinie en dbut
de Leon, et ils ne peuvent donner lieu au traitement indiffrenci d'instances de diverses
classes drives. En dpit de leur similarit de surface avec l'hritage public, les mcanismes
J-L Pris - 20/01/06
C++ - Leon 13 Classes drives 9/9
d'hritage protg et priv sont fonctionnellement plus proche du cas ou une classe possde
comme membre une instance d'une autre classe.

De fait, dans la plupart des cas, l'alternative considrer est entre une drivation (publique)
qui rend compte d'une vritable spcialisation (dans les cas o un Cl asseDer i vee est un
Cl asseDeBase) et une relation "possde un membre du type..." (dans les cas o un
Cl asseCompl exe comporte un Cl assePl usSi mpl e).

Ce n'est qu'exceptionnellement qu'il peut s'avrer plus avantageux de recourir un hritage
protg ou priv.
6 - Bon, c'est gentil tout a, mais a fait dj 8 pages. Qu'est-ce que
je dois vraiment en retenir ?
1) Lorsque diffrents types d'objets ont assez de caractristiques communes pour que des
traitements non triviaux puissent tre effectus sans savoir exactement quel type d'objet
on a affaire, il peut tre judicieux de crer une classe de base et des classes qui en sont
(publiquement) drives.

2) Lorsqu'une classe drive d'une classe de base, elle hrite des membres qui constituent
celle-ci. Les membres explicitement dclars dans la classe drive lui seront propres.

3) Constructeurs, destructeurs, oprateurs d'affectation et liens d'amiti ne sont jamais
hrits.

4) L'initialisation des membres hrits passe par l'excution d'un constructeur de la classe de
base.

5) La destruction d'une instance d'une classe drive passe par l'excution d'un destructeur de
la classe de base.

6) Le destructeur de la classe de base est en gnral insuffisant pour dtruire une instance
d'une classe drive.

7) Une fonction membre propre une classe drive n'a accs aux membres hrits que si
ceux-ci ne sont pas dclars pr i vat e: dans la classe de base.

8) Une classe peut tre drive d'une classe qui est elle-mme dj drive d'une autre. On
parle alors d'une hirarchie de classes et d'hritage indirect.

9) Une classe peut driver simultanment de plusieurs autres. On parle alors d'hritage
multiple.

10) La conception de hirarchies de classes impliquant l'hritage multiple n'est pas une
entreprise conseiller un dbutant.

11) Crer une classe par drivation d'une (ou plusieurs) classe(s) de base prvue(s) cet effet
est, en revanche, la porte de n'importe qui.

J-L Pris - 20/01/06