多重継承はそれを真実にしません。
それは完全に正しいわけではありません。この例を考えてみましょう:
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
のインスタンスを作成するときD、BおよびCはそれぞれのそれぞれのインスタンスでインスタンス化されますA。ただし、のインスタンスがのDインスタンスBとのそれぞれのインスタンスのアドレスが同じであれば問題はありませんA。必須ではありませんが、clang 11andでコンパイルすると、これが正確に起こり 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
仮想継承もそれを真実にしませんか
上記の例の修正版を考えてみましょう:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
virtual関数指定子の使用は通常、あいまいな関数呼び出しを回避するために使用されます。したがって、virtual継承を使用する場合はB、Cインスタンスとインスタンスの両方で共通のAインスタンスを作成する必要があります。をインスタンス化Dすると、次のアドレスが取得されます。
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)
次のコードは正しいですか
ここでを使用する理由はありませんreinterpret_cast。さらに、未定義の動作が発生します。static_cast代わりに使用:
A* pA = static_cast<A*>(pB);
この例では、両方のキャストの動作が異なります。reinterpret_cast再解釈されますpBへのポインタとしてA、しかしポインタはpA上記の例(A対C)のように、異なるアドレスを指すことができます。を使用すると、ポインタは正しくアップキャストされますstatic_cast。
reinterpret_castクラスの場合は常に怪しげです(クラスからvoid*、および同じクラスに戻ることを除く)。