Say we have base classes:
class CommonClass {
...
int common_value;
}
class ParentOfA {
...
int some_int;
int some_int_2;
}
class ParentOfB {
...
int some_int_3;
}
And we have inherited classes:
class ClassA : ParentOfA, CommonClass
class ClassB : ParentOfB, CommonClass
Then ClassA
and ClassB
will have structures look like this:
ClassA:
ParentOfA:
int some_int;
int some_int_2;
int common_value;
ClassB:
ParentOfB:
int some_int_3;
int common_value;
Therefore, for the same common_value
member variable, in ClassA
it's 8 bytes away from ClassA
's pointer, while in ClassB
it's only 4 bytes away.
Then in the following case (assume it's in .cpp file so compiled already):
int GetCommonValue(CommonClass* ptr) {
return ptr->common_value;
}
How does the compiler know ahead of time what offset to look up when handling ->common_value
? Both ClassA
and ClassB
may be passed in as pointers.
It's the caller's job to pass the correct address to the function. A pointer to a class always points to the beginning of the object of the same class - so that member offsets can work.
For single inheritance the base and the derived objects begin at the same address (in other words, the base part is at the beginning of the derived object).
With multiple inheritance this is not possible for all base classes - only one will begin at the same address as the derived object. This means that having object of type ClassA and three pointers to it - of types CommonClass, ParentOfA, and ClassA, when comparing the CommonClass and ParentOfA pointers, one of them will point to the same address as the ClassA pointer. The other one will point to different addres-to the beginning of the base class part, same as pointer's type.
Which pointer will point to the beginning of the object's memory location, depends on the order of the base parts in the derived object. This order is implementation defined.