Multiple inheritance and virutal functions

How is the size of an object affected during multiple inheritance involving virtual functions?

Answer:
For each inheritance hierarchy involving virtual functions, the size increases by the size of ptr to vtable ( 4 bytes ).

For ex:

#include
class A
{
public:
virtual void f() { printf( "%p %s \n", this, __func__ ); }
};
class B
{
public:
virtual void g() { printf( "%p %s \n", this, __func__ ); }
virtual void h() { printf( "%p %s \n", this, __func__ ); }
};

class C: public A, public B
{
void g() { B::g(); }
};
class D: public A
{
};

int main()
{
A* pa;
B* pb;
C c;
pb = &c;
pa = &c;
pb->g();
pa->f();
printf(" A %p , B %p, C %p \n", pa, pb, &c );
return printf(" A %d B %d C %d D %d \n",
sizeof(A),sizeof(B),sizeof(C),sizeof(D)
);
}


Gives the following output:

0xbfe81c58 g
0xbfe81c54 f
A 0xbfe81c54 , B 0xbfe81c58, C 0xbfe81c54
A 4 B 4 C 8 D 4


Here the size of C is printed as 8, because it get two vtable ptrs from A and B.
Also interesting to note that the "this" pointer values are different.
The Memory layout will look something like this:


+-----------+
| vptr----|-------->+-------------+
| A part | | &A::f | 0 | ( A & C's vtbl )
+-----------+ +-------------+
| vptr----|-------->+---------------------+
| B part | | &C::g | -delta(B) | ( B's vtbl:)
| | | &B::h | 0 |
+-----------+ +---------------------+
| C Part |
| |
+-----------+


During multiple inheritance, the vtbl also contains the detla adjustments for this pointer.

Sometimes, instead of delta, it contains the pointer to code which adjusts the this pointer the calls the actual virtual function ( called thunk ).

Reference : The Annotated C++ Reference Manual, p.241 Chapter 10

No comments: