next up previous contents
Next: Héritage virtuel Up: Héritage Previous: Héritage simple

Héritage multiple

tabular833

Pour une classe C héritant de A et de B :

tabular876

En apparence, rien n'a changé, pour l'appel de bf à partir de oc, il faut que le ``this'' correspondant à cet appel soit l'adresse d'une partie `` B'' ; pour cela, dans :

C* pc = new C;
pc->bf(0);
l'appel pc->bf(0) correspondra à :
((B *)((char *)(pc + delta(B))))->bf(0)
Cette transformation réalisée par le compilateur a quelques conséquences :
  1. conversion de pointeurs :

    Sans l'héritage multiple, la conversion de pointeurs ne pose pas de problème ; pour convertir un pointeur sur un objet d'un type dérivé en un pointeur sur un objet d'un type de base, il n'y a rien à faire : dans les deux cas il s'agit de la même adresse. Par contre, avec héritage multiple, il faudra éventuellement faire une déplacement :

    B *pb;
    pb = pc ;              // pb=(B*)((char *)(pc + delta(B)))
    pb = (B*)pc;           // idem

    Mais la conversion d'un pointeur sur objet de type C en un pointeur sur un objet de type A ne nécessitera (dans cet exemple !) aucune modification d'adresse.

  2. conversion de base vers dérivée : On peut par forçage de type réaliser une conversion vers un type dérivé, comme l'adresse d'une des parties correspondant au type de base n'est pas toujours identique à l'adresse de l'objet, la conversion pourra faire un déplacement d'adresse (inverse de celui de dérivée vers base)gif

    pc = pb ;              // interdit 
    pc = (C*)pb;           // pc=(C*)((char *)(pb - delta(B)))
  3. comparaison de pointeurs :

    Dans la comparaison des pointeurs si on a : pc == pb

    par conversion ce sera équivalent à : (B *)pc == pb

    ce qui revient à : (B*)((char *)(pc+delta(B))) == pb

    Et donc les pointeurs peuvent être ``égaux'' sans que les adresses soient identiques. Et on aura :

    tabular922

  4. pointeur nul : mais il faut que le pointeur nul reste nul ...malgré les conversions.
    C* pc=0;
    B* pb=pc;
    if (pb == 0) { ... } 
    if (pb == pc) { ...}
    La conversion réellement réalisée est :
    pb=pc;     // (pc==0)?0:(B*)((char *)(pc+delta(B)))




Mon Oct 20 14:02:48 MET 1997