Témoignage
 

Rubrique « Info »

 



Écrivez à AILES !



Retour vers programmation



Retour vers les questions C++
 


Questionnaire C++
Héritage multiple

[AnnotatedC++], pp.198 et suiv.


L'héritage multiple provoque, de nos jours (1999), une réaction de plus en plus timide : on trouve cela "dangereux", "risqué", voir même "preuve d'une mauvaise modélisation"!...
Java a depuis longtemps tranché et en a purement et simplement interdit l'usage, lui préférant "l'implémentation d'interfaces multiples".
Pourquoi donc ? Le petit questionnaire suivant va vous le démontrer : gérer en mémoire des instances issues d'un héritage multiple, cela n'a rien d'évident.

A quoi sert l'héritage multiple ?
(Réponses à toutes les questions de cette page)



Classe de base :

une classe dérivée peut-elle hériter deux fois d'une même classe de base :
- directement ?
class D1 : public B, public B { /* ... */ } ;
- indirectement ?
class A : public L { /* ... */ } ;
class B : public L { /* ... */ } ;
class D2 : public A, public B { /* ... */ } ;
- dans le deuxième cas, quel est le graphe acyclique dirigé décrivant le mieux la situation ?

ou bien

Peut-on caster D2 en L ?
(Réponses à toutes les questions de cette page)



Héritage virtuel
Décrivez par un graphe acyclique dirigé la situation suivante :
class B : { /* ... */ } ;
class X : virtual public B { /* ... */ } ;
class Y : virtual public B { /* ... */ } ;
class Z : public B { /* ... */ } ;
class DDD : public X, public Y, public Z { /* ... */ } ;


Dans ce dernier cas, comment la fonction virtuelle f() de B, redéfinie dans X, Y, Z doit elle être implémentée dans DDD afin d'appeler sans conflit chacune des versions de f() de ses classes mères ?
class B
{
public:
   virtual void f() ;
};
void DDD::f()
{
   ...
   X::f() ; Y::f() ; Z::f() ; // ? suffisant ?
}

(Réponses à toutes les questions de cette page)



Ambiguïtés
C'est bon ? Pas trop mal à la tête ?... Allez, on passe la seconde.
class V
{
public:
   int f() ;
   int fff() ;
   int v ;
   int vvv ;
};
class A
{
public:
   int a ;
   static int static_a ;
   enum {e} ;
};
class B : public A, public virtual V
{
public:
   int f() ;
   int x ;
   int fff() ;
};
class C : public A, public virtual V
{
private:
   char * vvv ;
};
class D : public B, public C
{
   void g() ;
};
class DDD : public B, public virtual V
{
};
Avant de préciser si la fonction suivante comporte ou non une ou plusieurs ambiguités, faite un diagramme acyclique de la situation, avec les attributs et les fonctions respectives de chaques classes.
Surtout, faites-le.
Surtout.
void D:: g()
{
   v++; // ambigüe ou non ?
   a++; // ambigüe ou non ?
   x++; // ambigüe ou non ?
   f() ; // ambigüe ou non ?
   static_a = 1 ; // ambigüe ou non ?
   int i = e ; // ambigüe ou non ?

   B* p_b = this ; // ambigüe ou non ?
   A* p_a = this ; // ambigüe ou non ?
   V* p_v = this ; // ambigüe ou non ?

   int my_vvv = vvv ;
}

Quelle est la fonction f() appelée dans ggg() ? V::f() ou B::f() ?
void ggg( B* p_b, DDD* p_ddd )
{
   p_b->f() ; // V::f() ou B::f() ?
   p_ddd->f() ; // V::f() ou B::f() ?
}

(Réponses à toutes les questions de cette page)




Fonctions virtuelles
okok, on respire... on inspire... on expire... on inspire un grand coup : c'est reparti.
Les questions sont en commentaires :
class V
{
public :
   static virtual int sf() ; // possible ?
   virtual int f() ;
   virtual int g( V* ) ;
   virtual V* h() ;
};
class A : public V
{
   int f() // f est-elle virtuelle
   {
      f() ; // quelle f() est appelé ?
   };
   virtual int g( A* ) ; // s'agit-il de la même fonction virtuelle que V::g() ?
   virtual A* h() ; // s'agit-il de la même fonction virtuelle que V::h() ?
};


Considérez les classes A, B et C :

class A
{
public :
   virtual void f() { printf("A::f()") ; }
   A() {}
};
class B : public A
{
public :
   B() { f() ; }
// appelle la fonction virtuelle f()
   void g() { f() ; }
// appelle la fonction virtuelle f()
};
class C : public B
{
public :
   virtual void f() { printf("C::f()") ; }
   C() {}
};
Que produit le code suivant ?
main()
{
   C c ;
   c.g() ;
}

Ultime question : fonctions virtuelles avec héritage virtuel. soit :

Toutes les fonctions sont virtuelles. AL et BL ont un héritage virtuel vers LL.
quelle est la fonction f() invoquée par le code suivant ?

void ma_fonction( ABL* p_abl )
{
   BL* p_bl = (BL*)p_abl ;
   p_bl->f() ;
// LL::f() ou AL::f() ou error ???
}

Remarque : la dernière question de la prochaine rubrique propose une autre façon de répondre à la même question...

(Réponses à toutes les questions de cette page)




Héritage multiple et représentation en mémoire
Dernière ligne droite... et là, ça devient vraiment coton...
Quelle est la représentation mémoire correcte d'un objet de type C, sachant que C dérive des classes A et B ?

ou bien

Considérez que A possède une fonction fa(), B une fonction fb() et C un fonction fc().
Comment, dans le cadre de la première représentation mémoire (celle de gauche), traduiriez-vous :
C* p_c = new C() ;
p_c->fb() ; ?
Indice :
Les adresses mémoire de p_c et (B*)p_c sont-elles les mêmes ?
Oui ?
Non ?
Si non, et si p_b = (B*)p_c, est-ce que (p_c == p_b) est true ou false ?
Si non, pourquoi le code suivant marche-t-il quand-même ?
C* p_c = 0 ;
B* p_b = 0 ;
if( p_c == 0 ) { /* ... */ }
p_b = p_c ;
if( p_b == 0 ) { /* ... */ }
En effet, si le fait de caster un C* en B* devait entraîner un décalage mémoire, p_b devrait changer puisque p_b vaut un cast implicite de p_c en B*... alors ?

Quelle est la représentation mémoire d'un héritage virtuel tel que celui-ci ?

Ultime question : héritage virtuel avec fonctions virtuelles, le tout en mémoire!
Reprenons l'héritage virtuel présenté en fin de rubrique précédente :

Représentez les tableaux de pointeurs vers les fonctions virtuelles telles que chaque parties de l'objet ABL doit les stocker.
Ces tableaux sont, pour chacune des fonctions f(), g(), h() et k(), composé d'un offset permettant de retomber sur le début de la bonne fonction.
Remarque : la dernière question de la précédente rubrique propose une autre façon de trouver un début de réponse à la même question...

(Réponses à toutes les questions de cette page)





               
 
Avertissement !
 
Décollage !  |  Présentation du site web "AILES"  | 
Infos générales  |  articles "Informatique"