菱形继承和虚基表
虚基表指针
子类虚继承父类:编译器自动在子类对象头部插入 vbptr。
子类普通继承含虚基表指针的父类:子类不创建新的vbptr,复用父类的 vbptr,并创建新的虚基表
虚基表
1.虚基表的本质是个偏移量数组,偏移量是子类对象中虚基表指针到虚基类对象的偏移量
多虚继承
class A { int a; };
class B { int b; };
class C : virtual public A, virtual public B { int c; }; // 多虚继承的对象结构内存偏移 存储内容 说明
0 C::vptr (或 vbptr) 指向 C 的虚基表(vbtable),存储 A 和 B 的偏移量。
4 C::c C 的成员变量 c。
8 A::a 虚基类 A 的成员(由于虚继承,A 只存储一份)。
12 B::b 虚基类 B 的成员(由于虚继承,B 只存储一份)。
class A { int a; };
class B : virtual public A { int b; };
class C : virtual public A { int c; };
class D : public B, public C { int d; };内存偏移 内容 说明
0 B::vptr 指向 B 的虚函数表
4 B::b B 的成员变量
8 C::vptr 指向 C 的虚函数表
12 C::c C 的成员变量
16 D::d D 的成员变量
20 A::a 共享的 A 子对象
虚函数加多虚继承
class A { virtual void foo() {} int a; };
class B : virtual public A { virtual void bar() {} int b; };
class C : virtual public A { virtual void baz() {} int c; };
class D : public B, public C { void foo() override {} int d; };偏移 内容 说明
0 B::vptr 指向 B 的虚函数表
4 B::vbptr 指向 B 的虚基表
8 B::b B 的成员变量
12 C::vptr 指向 C 的虚函数表
16 C::vbptr 指向 C 的虚基表
20 C::c C 的成员变量
24 D::d D 的成员变量
28 A::vptr 指向 A 的虚函数表
32 A::a A 的成员变量