Se si dispone di un void * puntatore alla classe derivata che eredita da entrambi BaseA
e BaseB
, come fa il compilatore il cast del puntatore void*
a BaseA*
(o BaseB*
) senza sapere che il puntatore void*
è di tipo Derived
?Casting con l'ereditarietà multipla
risposta
Non funziona. L'unica garanzia quando lancia in e da una void*
utilizzando un static_cast
è:
Un valore di tipo puntatore di opporsi convertito in "puntatore a
cv void
" e ritorna al tipo di puntatore originale avrà il suo valore originale (C + +03 §5.2.9/10).
Ad esempio, il codice seguente è corretto poiché il void*
è gettata a un tipo diverso dal tipo puntatore originale (la sequenza cast è 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);
tentativo utilizzare b2ptr
qui comporterebbe un comportamento indefinito. L'unico tipo con il quale è possibile trasmettere in modo sicuro voidptr
è B1*
, poiché questo è il tipo da cui è stato ottenuto il valore (bene, o su un valore char*
, poiché è possibile accedere a qualsiasi elemento tramite char*
).
Il compilatore non lancia il puntatore void*
su qualsiasi cosa: tu, il programmatore, fai.
Al fine di fare qualcosa di utile con un puntatore void*
, è necessario esplicitamente cast a un puntatore non void*
, e se ti sbagli su ciò che digitare il puntatore in realtà indica, si entra Non definito Comportamento Città .
La tua risposta è corretta. Dalla mia ricerca se Derived estende BaseA e BaseB, l'oggetto è disposto in memoria come | BaseA | BaseB | Derivato |. Quindi il puntatore punta verso l'inizio di BaseA, quindi il cast di Derivati in BaseB ti farà leggere i membri di BaseA. – Chazz