我试图用虚拟表和继承来理解一些低级的东西。
当您通过继承两个类并添加新的虚函数来创建新类时,vptr 将存储在哪里?
在我看来,在这种情况下,编译器会执行一些“vptr 优化”。我正试图弄清楚。
假设我们有以下结构:
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();
};
在 x86 和 align=4 的情况下,A
在B
内存中将如下所示:
+------+------+
A: | vptr | a |
+------+------+
sizeof(A) = 4 + 4 = 8
+------+------+------+------+
B: | vptr | b |
+------+------+------+------+
sizeof(B) = 8 + 8 = 16
但是当我尝试重新组装时C
,我得到了这个:
+------+------+------+------+------+------+------+
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
那么vptr在C
哪里呢?我可以假设编译器合并不同的虚拟表(例如 vptr of A
and C
),但在那种情况下为什么sizeof(C)
返回sizeof(A)
++ sizeof(sizeof(B)
vptr sizeof(alligned_char)
)
有同样的struct D : public C {}
故事 - 没有 vptr 的D
。
我使用的编译器是 msvc 2012 x86。