2010-07-25 7 views
6

Si vous avez un pointeur void * à la classe dérivée qui hérite de deux BaseA et BaseB, comment le compilateur jeté le pointeur void* à BaseA* (ou BaseB*) sans savoir que le pointeur void* est de type Derived?casting avec l'héritage multiple

Répondre

5

Ce n'est pas le cas. La seule garantie lors de la coulée depuis et vers un void* en utilisant un static_cast est:

Une valeur de pointeur de type à objet converti en « pointeur vers cv void » et revenir au type de pointeur d'origine aura sa valeur d'origine (C + +03 §5.2.9/10).

Par exemple, le code suivant est incorrect parce que le void* est coulée à un type autre que le type de pointeur d'origine (la séquence coulée est B1* ->void* ->B2*):

struct B1 { int i; }; 
struct B2 { int j; }; 

struct D : B1, B2 { }; 

D x; 
B1* b1ptr = &x; 
void* voidptr = b1ptr; 
B2* b2ptr = static_cast<B2*>(voidptr); 

Tentative utiliser b2ptr entraînerait un comportement indéfini. Le seul type auquel vous pouvez lancer en toute sécurité voidptr est B1*, puisque c'est le type à partir duquel le void* a été obtenu (bien, ou à un char*, puisque tout est accessible via un char*).

3

Le compilateur ne lance pas le pointeur void* en quoi que ce soit - vous, le programmeur, le faites.

Afin de faire quelque chose d'utile avec un pointeur void*, vous devez explicitement à un casting pointeur non void*, et si vous avez tort sur le type le pointeur indique en fait, vous entrez Undefined Ville Comportement .

+0

Votre réponse est correcte. De mes recherches, si Derived étend BaseA et BaseB, l'objet est mis en mémoire sous | BaseA | BaseB | Dérivé |. Ainsi, le pointeur pointe vers le début de BaseA, ce qui vous permet de lire les membres de BaseA. – Chazz