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
, B
y C
se instancian cada uno con su instancia respectiva de A
. Sin embargo, no habría ningún problema si la instancia de D
tuviera la misma dirección de su instancia de B
y su respectiva instancia de A
. Aunque no es obligatorio, esto es exactamente lo que sucede al compilar clang 11
y 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 virtual
especificador de funciones se usa generalmente para evitar llamadas ambiguas a funciones. Por lo tanto, cuando se usa la virtual
herencia, ambos B
y las C
instancias deben crear una A
instancia 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_cast
lugar:
A* pA = static_cast<A*>(pB);
Ambos lanzamientos se comportan de manera diferente en este ejemplo. La reinterpret_cast
reinterpretará pB
como un puntero a A
, pero el puntero pA
puede 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_cast
with classes es siempre sospechoso (excepto de clase avoid*
, y de regreso a la misma clase).