Pour une classe C héritant de A et de B :
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 :
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.
pc = pb ; // interdit pc = (C*)pb; // pc=(C*)((char *)(pb - delta(B)))
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 :
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)))