文章目录
- 一、不存在virtual的对象和继承结构
- 二、基类包含virtual的单继承结构
- 2.1、派生类不覆盖虚函数的情况
- 2.2、派生类覆盖虚函数的情况
- 三、基类中包含virtual的多继承结构
- 3.1、派生类中未覆盖基类中的虚函数
- 3.1、派生类中覆盖了基类中的虚函数
- 四、虚继承下单继承结构
- 4.1、派生类未覆盖基类的虚函数
- 4.2、派生类覆盖了基类的虚函数
一、不存在virtual的对象和继承结构
这种情况没什么好说的,继承情况下对象会将基类对象的所有成员都继承过来,只是private成员不可访问。
二、基类包含virtual的单继承结构
2.1、派生类不覆盖虚函数的情况
class A {
virtual void func() {}
int ma;
};
class B : public A {
int mb;
};
对象的内存布局如下图所示:
vtable内容如下图所示:
基类中有virtual函数,所以A中多了一个vtable,B中将A中所有的内容继承下来,再加上自己的成员。
2.2、派生类覆盖虚函数的情况
class A {
virtual void func() {}
int ma;
};
class B : public A {
virtual void func() {}
int mb;
};
对象的内存布局不变,因为成员变量和继承结构没有改变。
vtable的内容如下图所示:
三、基类中包含virtual的多继承结构
3.1、派生类中未覆盖基类中的虚函数
class A {
virtual void funcA() {}
int ma;
};
class B {
virtual void funcB() {}
int mb;
};
class C : public B, public A {
int mc;
void func() {}
};
对象的内存布局如下图所示:
很好理解,按照继承的顺序将基类中的成员变量和vtable pointer继承过来,vtable内容如下图所示:
派生类的vtable会先将第一继承的基类的虚表拿过来,然后在RTTI中留下信息,然后再将第二继承的基类虚表拿过来。
3.1、派生类中覆盖了基类中的虚函数
class A {
virtual void funcA() {}
int ma;
};
class B {
virtual void funcB() {}
int mb;
};
class C : public B, public A {
int mc;
void funcA() {}
void func() {}
};
对象的内存布局没有变化,因为成员变量和继承结构没有发生变化,vtable内容如下图所示:
注意派生类的虚函数表中两个虚函数是放在一块儿的。
四、虚继承下单继承结构
4.1、派生类未覆盖基类的虚函数
class A {
virtual void funcA() {}
int ma;
};
class B : virtual public A {
virtual void funcB() {}
int mb;
};
对象内存布局如下图所示:
此时派生类有了自己单独的vtable pointer,vtable内容如下图所示:
4.2、派生类覆盖了基类的虚函数
对象内存布局不变,因为继承结构和成员变量没有发生改变,
vtable内容如下图所示: