Vous êtes sur la page 1sur 8

Ecole Nationale de Techniques Avancées

Simulation Numérique
Chapitre 6
Héritage
Eric Lunéville
Qu’est ce que l’héritage de classe?
Classe descendant (dérivant) d’une autre classe (mère)
Exemple : matrice
Matrice dimensions, valeurs
Matrice_pleine Matrice_bande Matrice_profil
Données supplémentaires (largeur de bande, vecteur profil)
Accès terme i,j et opérations (algorithmes spécifiques)
fonctionnalités communes (classe mère)
fonctionnalités communes mais implémentation différente (classes enfants)
fonctionnalités spécifiques (classes enfants)
Le C++ permet de gérer ces mécanismes
Avantage : factorisation du code, robustesse, lisibilité, sécurité
Sim. Numérique – chapitre 6 - 1
Plan
Syntaxe de la dérivation
Fonctions membres
Constructeurs/destructeur
Transtypage
Fonctions virtuelles
Classe abstraite, interface
Polymorphisme
Conception de classes hiérarchisées
Sim. Numérique – chapitre 6 - 2
Syntaxe de la dérivation
Syntaxe pour une classe fille dérivant d'une classe mère
class fille : type_héritage mère { … };
la classe fille hérite selon type_héritage :
type_héritage membre public membre protected membre private
public public protected inaccessible
protected protected protected inaccessible
private private private inaccessible
membre protected : accessible seulement à la classe mais héritable
membre private : accessible seulement à la classe mais inhéritable
Héritage le plus courant : public (ne change pas les droits)
Sim. Numérique – chapitre 6 -3
Exemple de dérivation
class matrice
{ protected : i n t dim ;
double ∗ v a l ; constructeur privé !!!
private : matrice ( ) ;
public : i n t dim ( ) { return dim ; } pas d’instanciation de matrice
};
c l a s s e m a t r i c e p l e i n e : public m a t r i c e
{ public : m a t r i c e p l e i n e ( int , double ) ; constructeur public
double & operator ( ) ( i n t i , i n t j )
{ return v a l [ ( j −1)∗ dim +i − 1 ] ; }
opérateur d’accès
};
c l a s s e m a t r i c e b a n d e : public m a t r i c e
{ protected : i n t l g b a n d e ; largeur de bande
public : m a t r i c e b a n d e ( int , int , double ) ;
double & operator ( ) ( i n t i , i n t j ) ; constructeur public
}; opérateur d’accès
- dim_ et val_ restent protégés et accessibles aux classes dérivées
- 2 implémentations de l'opérateur d’accès ()
Sim. Numérique – chapitre 6 -4
Création/destruction
Constructeur de la classe de base, puis de la classe dérivée
Destructeur de la classe dérivée, puis de la classe de base
class matrice
{ protected : i n t dim ; // dimension
int nb val ; //nombre de v a l e u r s
double ∗ v a l ; // v a l e u r s
public : m a t r i c e ( i n t n ) : dim ( n ) { v a l =NULL; } // c o n s t r u c t e u r
};
c l a s s e m a t r i c e p l e i n e : public m a t r i c e
{ public : m a t r i c e p l e i n e ( int n ) // c o n s t r u c t e u r
: m a t r i c e ( n ) { n b v a l=dim ∗ dim ; v a l =new double [ n b v a l ] ; }
};
c l a s s e m a t r i c e b a n d e : public m a t r i c e
{ protected : i n t l g b a n d e ; // l a r g e u r de bande
public : m a t r i c e b a n d e ( i n t n , i n t l ) // c o n s t r u c t e u r
: matrice (n ) , lg bande ( l )
{ n b v a l=n ∗ ( 2 ∗ l +1)− l ∗ ( l +1) ; v a l =new double [ n b v a l ] ; } }
};
Appel explicite au constructeur de la classe mère
matrice_pleine(int n) : dim_(n){...}
erreur : initialisation de dim_ par matrice_pleine !
Sim. Numérique – chapitre 6 -5
Dérivation hiérarchique et multiple
Dérivation d'une classe dérivée :
même syntaxe, la classe mère est une classe dérivée
c l a s s m a t r i c e p l e i n e s y m e t r i q u e : public m a t r i c e p l e i n e
{ public : double & operator ( ) ( i n t i , i n t j ) } ;
Dérivation multiple : classe ayant plusieurs mères
class fille : type_héritage mère1, type_héritage mère2 { … };
class matrice class p r o f i l
{ protected : { protected :
i n t dim ; int ∗ p r o f i n f ;
double ∗ v a l ; }; int ∗ prof sup ;
double & operator ( ) ( int , i n t ) ; };
c l a s s m a t r i c e p r o f i l : public m a t r i c e , public p r o f i l
{ . . . };
Nécessite une bonne réflexion
Peut résulter de contraintes (réutilisation de classes)
Sim. Numérique – chapitre 6 -6
Surcharge des fonctions membre
Surcharge implicite des fonctions membre
class matrice //PLEINE
{ protected : i n t dim ; //non p r i v e
double ∗ v a l ; // a c c e s p o s s i b l e par l e s d e s c e n d a n t s
public : m a t r i c e ( int , double ) ; // c o n s t r u c t e u r
i n t dim ( ) { return dim ; } // a c c e s à l a dimension
double & operator ( ) ( i n t i , i n t j ) // a c c e s v a l e u r s
{ return v a l [ ( j −1)∗ dim +i − 1 ] ; }
};
c l a s s e m a t r i c e b a n d e : public m a t r i c e
{ protected : i n t l g b a n d e ; // l a r g e u r de bande
public : m a t r i c e b a n d e ( int , int , double ) // c o n s t r u c t e u r
double & operator ( ) ( i n t i , i n t j ) ; // a c c e s v a l e u r s
};
Ici matrice est une matrice pleine !
int main ( )
{ m a t r i c e A( 3 , 0 ) ; A(1,1) : matrice:: () (1,1)
matrice bande B( 3 , 2 , 1 . ) ;
B(2,1) : matrice_bande:: () (2,1)
A( 1 ,1)=B ( 2 , 1 ) ;
}
Sim. Numérique – chapitre 6 -7
Accès aux fonctions de la classe mère
Appel d'une fonction membre de la classe mère surchargée
class matrice //PLEINE
{ protected : i n t dim ; //non p r i v e
double ∗ v a l ; // a c c e s p o s s i b l e par l e s d e s c e n d a n t s
public : ...
void p r i n t ( ) ; // i m p r e s s i o n de l ’ e n t e t e ( dim )
{ cout<<”\ n m a t r i c e de d i m e n s i o n ”‘<<dim ;
};
c l a s s e m a t r i c e b a n d e : public m a t r i c e
{ protected : i n t l g b a n d e ; // l a r g e u r de bande
public : ...
void p r i n t ( ) // i m p r e s s i o n ma t r i c e bande
{ matrice : : print ( ) ; //APPEL p r i n t ( ) c l a s s e mere
cout<<” de t y p e bande , l a r g e u r = ”‘<< l g b a n d e ;
...
}
};
Appel de la fonction print de la classe mère
l'oubli de matrice :: provoque un appel récursif infini !!!
Sim. Numérique – chapitre 6 -8
Copie
Attention aux opérations de copie :
class matrice
{ protected : i n t dim ; // dimension
int nb val ; //nombre de v a l e u r s
double ∗ v a l ; // v a l e u r s
public : m a t r i c e ( const m a t r i c e & M) ; // c o p i e
};
c l a s s e m a t r i c e b a n d e : public m a t r i c e
{ protected : i n t l g b a n d e ; // l a r g e u r de bande
public : m a t r i c e b a n d e ( const m a t r i c e b a n d e & M) ; // c o p i e
};
i n t main ( )
{ m a t r i c e bande A( 1 0 , 2 ) ;
m a t r i c e B=A; // a p p e l de l a c o p i e de ma t r i c e e t non de m a t r i c e b a n d e
}
Équivalent au constructeur matrice(A)
Même remarque pour l’opérateur =
Sim. Numérique – chapitre 6 -9
Transtypage
Transtypage d'un pointeur sur un objet de la classe fille
en un pointeur sur un objet de la classe mère :
classe_mere * pM=(classe_fille *) pF}
Le contraire (non détecté à la compilation) est dangereux !
Déterminer le type d'un objet dérivé à partir de son pointeur sur la
classe mère ?
pF=dynamic_cast<classe_mere *> (pMere)
- retourne un pointeur NULL si le transtypage est impossible !
- relève de l’exécution (Run Time Information)
contrairement au transtypage statique (static_cast)
void f ( const m a t r i c e ∗pM)
{ m a t r i c e b a n d e ∗pMB;
pMB=dynamic cast <m a t r i c e b a n d e > (pM) ; // t r a n s t y p a g e dynamique
i f (pMB==NULL)
{ c out<<” e r r e u r M n ’ e s t pas une m a t r i c e bande ” ; e x i t ( 1 ) ; }
...
}
Sim. Numérique – chapitre 6 -10
Fonction membre virtuelle
Une fonction membre d'une classe peut-être déclarée virtual :
- elle a une implémentation usuelle
- les classes dérivées peuvent implémenter la même fonction
- l'appel de la fonction depuis la classe mère appellera la fonction
de la classe dérivée adéquat ( polymorphisme)
class matrice
{ v i r t u a l void p r i n t ( ) { c o u t <<” m a t r i c e de d i m e n s i o n ”<<dim ; }
};
c l a s s m a t r i c e p l e i n e : public m a t r i c e
{ void p r i n t ( ) { c o u t <<” m a t r i c e p l e i n e de d i m e n s i o n ”<<dim ; . . . }
};
class matrice bande : public m a t r i c e
{ void p r i n t ( ) { c o u t <<” m a t r i c e bande de d i m e n s i o n ”<<dim ; . . . }
};
i n t main ( )
{ m a t r i c e ∗A=( m a t r i c e ∗ ) ( m a t r i c e p l e i n e ( 1 0 ) ) ;
m a t r i c e ∗B=( m a t r i c e ∗ ) ( m a t r i c e b a n d e ( 1 0 ) ) ;
A−>p r i n t ( ) ; // a p p e l de m a t r i c e p l e i n e : : p r i n t ( ) ;
B−>p r i n t ( ) ; // a p p e l de ma t r i c e b a n d e : : p r i n t ( ) ;
}
Sim. Numérique – chapitre 6 -11
Classe abstraite, interface
L'implémentation de matrice::print() est inutile si les classes dérivées
proposent la fonction print()
fonction virtuelle pure (pas d'implémentation) : virtual void print() = 0;
class matrice
{ v i r t u a l void p r i n t ( ) = 0 ; // v i r t u e l l e pure
};
c l a s s m a t r i c e p l e i n e : public m a t r i c e
{ void p r i n t ( ) { c o u t <<” m a t r i c e p l e i n e de d i m e n s i o n ”<<dim ; . . . }
};
class matrice bande : public m a t r i c e
{ void p r i n t ( ) { c o u t <<” m a t r i c e bande de d i m e n s i o n ”<<dim ; . . . }
};
- toutes les classes dérivées doivent implémenter print()
- la classe matrice devient abstraite
- impossible d'instancier un objet de la classe matrice
- classe ayant le rôle d’une interface
Sim. Numérique – chapitre 6 -12
Conception de classes hiérarchisées
s'appuie sur l'identification des concepts sous-jacents;
une classe représente un concept
hiérarchie : du général au particulier
ne s'appuie pas sur des considérations de programmation
exemple : matrice stockage plein, bande, symétrique ou non
abstraite
matrice_base
matrice_pleine_base matrice_ bande_base
matrice_pleine matrice_pleine_sym matrice_bande matrice_bande_sym
demande à l'utilisateur de connaître le type de ses matrices
Sim. Numérique – chapitre 6 -13
Conception de classes hiérarchisées
Dissociation des concepts matrice et stockage
Classes de stockage
abstraite
stock_base
stock_plein_base stock_ bande_base
stock_plein stock_plein_sym stock_bande stock_bande_sym
classe de matrice générique template <class stock> matrice;
permet de traiter les cas de matrices non-symétriques à stockage symétrique !
- non unicité de la solution
- héritage multiple non strictement nécessaire
- hiérarchie complexe difficile à gérer
- dans tous les cas il faut bien réfléchir ...
Sim. Numérique – chapitre 6 -14