I'm trying to undestand some low-level things with virtual table and inheritance.
When you create new class by inheriting two classes and adding new virtual functions, where exactly the vptr will be stored?
It seems to me, that compiler performs some 'vptr-optimization' in that case. And I'm trying to figure it out.
Suppose, we have the following structs:
struct A
{
int a;
virtual void fa();
};
struct B
{
double b;
virtual void fb();
};
struct C : A, B
{
char c;
virtual void fa();
virtual void fb();
virtual void fc();
};
In case of x86 and align=4, A
and B
in memory will look like this:
+------+------+
A: | vptr | a |
+------+------+
sizeof(A) = 4 + 4 = 8
+------+------+------+------+
B: | vptr | b |
+------+------+------+------+
sizeof(B) = 8 + 8 = 16
But when I try to reassemble C
, I get this:
+------+------+------+------+------+------+------+
C: | vptr | a | vptr | b | c |
+------+------+------+------+------+------+------+
but sizeof(C) = 32
С с;
(C*)&c; // 0x100
(B*)&c; // 0x108
(A*)&c; // 0x100
&c.a; // 0x104
&c.b; // 0x110
&c.c; // 0x118
So where is the vptr of C
? I can suppose that compiler merge different virtual tables (ex. vptr of A
and C
), but in that case why sizeof(C)
returns sizeof(A)
+ sizeof(B)
+ sizeof(alligned_char)
+ sizeof(vptr)
The struct D : public C {}
has the same story - there is no vptr of D
.
The compiler I use is msvc 2012 x86.
A virtual table contains one entry for each virtual function that can be called by objects of the class. Each entry in this vTable is simply a Function Pointer that points to the most-derived function accessible by that class ie the most Base Class.
The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable.
In computer programming, a virtual method table (VMT), virtual function table, virtual call table, dispatch table, vtable, or vftable is a mechanism used in a programming language to support dynamic dispatch (or run-time method binding).
Which classes can have vtable? Explanation: Classes having virtual functions only need vtable because in those cases only we need to resolve function calls in a dynamic manner.
The compiler has to juggle simplicity, with the fact that the base classes need to exist within the object.
+------+---------+----+
| A | B | C |
+------+---------+----+
So
virtual functions from A and B will be patched for the derived class C's implementation.
C will add virtual functions to (probably) the existing first element A
s vtable.
base vtable for A
+------+
| A:fa |
+------+
vtable for A
in the derived class C
+------+
| C:fa | // implemented by derived class.
+------+
| C:fb | // any calls to fb need to be sent to `C`'s implementation
+------+
| C:fc | // any calls to fc can be overridden by vtable.
+------+
vtable for B
in the derived class C
+------+
| C:fb | // overridden, but no need to add fc, fa to this table.
+------+
I think alignment rules are causing the size of C
to be padded so the alignment sensitive double is correctly aligned (ensure that an array of C
is properly aligned).
The size of B
is the size of the vptr
(4) and padding to ensure the double
is aligned (4) and the size of the double
(8)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With