I would like to know how c++ ensures the concept layout in memory of these classes to support inheritance.
for example:
class Base1
{
public:
void function1(){cout<<"Base1"};
};
class Base2
{
public:
void function2(){cout<<"Base2"};
};
class MDerived: Base1,Base2
{
public:
void function1(){cout<<"MDerived"};
};
void function(Base1 *b1)
{
b1->function1();
}
So when I pass function an object of derived type the function should offset into the base1 class function and call it. How does C++ ensure such a layout.
When a
MDerived*needs to be converted to aBase1*, the compiler adjusts the pointer to point to the correct memory address, where the members of this base class are located. This means that aMDerived*that is cast to aBase1*might point to a different memory address than the originalMDerived*(depending on the memory layout of the derived class).The compiler can do this because it knows the memory layout of all the classes, and when a cast occurs it can add code that adjusts the address of the pointer.
For example this might print different addresses:
In your example such adjustments might not be necessary since the classes don’t contain any member variables that would use any memory in the sub-objects representing the base classes. If you have a pointer pointing to “nothing” (no member variables), it doesn’t really matter if that nothing is called
Base1orBase2orMDerived.The non-virtual methods of the classes are not stored with each object, they are stored only once. The compiler then statically, at compile time, uses those global addresses when a member function is called, according to the type of the variable used.