La herencia múltiple hace que eso sea falso.
Eso no es del todo correcto. Considere este ejemplo:
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
Al crear una instancia de D, By Cse instancian cada uno con su instancia respectiva de A. Sin embargo, no habría ningún problema si la instancia de Dtuviera la misma dirección de su instancia de By su respectiva instancia de A. Aunque no es obligatorio, esto es exactamente lo que sucede al compilar clang 11y gcc 10:
D: 0x7fffe08b4758 // address of instance of D
B: 0x7fffe08b4758 and A: 0x7fffe08b4758 // same address for B and A
C: 0x7fffe08b4760 and A: 0x7fffe08b4760 // other address for C and A
¿La herencia virtual también hace que eso sea falso?
Consideremos una versión modificada del ejemplo anterior:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
El uso del virtualespecificador de funciones se usa generalmente para evitar llamadas ambiguas a funciones. Por lo tanto, cuando se usa la virtualherencia, ambos By las Cinstancias deben crear una Ainstancia común . Al crear instancias D, obtenemos las siguientes direcciones:
D: 0x7ffc164eefd0
B: 0x7ffc164eefd0 and A: 0x7ffc164eefd0 // again, address of A and B = address of D
C: 0x7ffc164eefd8 and A: 0x7ffc164eefd0 // A has the same address as before (common instance)
¿Es correcto el siguiente código?
Aquí no hay ninguna razón para usar reinterpret_cast, aún más, resulta en un comportamiento indefinido. Use en su static_castlugar:
A* pA = static_cast<A*>(pB);
Ambos lanzamientos se comportan de manera diferente en este ejemplo. La reinterpret_castreinterpretará pBcomo un puntero a A, pero el puntero pApuede apuntar a una dirección diferente, como en el ejemplo anterior (C vs A). El puntero se subirá correctamente si lo usa static_cast.
reinterpret_castwith classes es siempre sospechoso (excepto de clase avoid*, y de regreso a la misma clase).