A herança múltipla torna isso falso.
Isso não está totalmente correto. Considere este exemplo:
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
Ao criar uma instância de D, Be Csão instanciados, cada um com sua respectiva instância de A. No entanto, não haveria problema se a instância de Dtivesse o mesmo endereço de sua instância de Be sua respectiva instância de A. Embora não seja necessário, é exatamente isso que acontece ao compilar com clang 11e 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
A herança virtual também torna isso falso
Vamos considerar uma versão modificada do exemplo acima:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
O uso do virtualespecificador de função geralmente é usado para evitar chamadas de função ambíguas. Portanto, ao usar virtualherança, as instâncias Be Cdevem criar uma Ainstância comum . Ao instanciar D, obtemos os seguintes endereços:
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)
O código a seguir está correto
Aqui não há razão para usar reinterpret_cast, ainda mais, isso resulta em um comportamento indefinido. Use em static_castvez disso:
A* pA = static_cast<A*>(pB);
Ambos os modelos se comportam de maneira diferente neste exemplo. O reinterpret_castreinterpretará pBcomo um ponteiro para A, mas o ponteiro pApode apontar para um endereço diferente, como no exemplo acima (C vs A). O ponteiro será convertido corretamente se você usar static_cast.
reinterpret_castcom classes é sempre suspeito (exceto da classe paravoid*e volta para a mesma classe).