文章目录
单个继承,带虚函数
- 在派生类对象的存储空间的开始 多一个虚函数指针
vfptr
- 若派生类有自己的虚函数,则会将其加入到派生类的虚表中
多重继承,带虚函数
- 每个基类都有自己的虚函数表
- 若派生类有自己的虚函数,则会将其加入到派生类的第一个虚表中
- 加快访问速度
- 派生类对象的存储空间布局是按照继承时的声明顺序
- 派生类中重定义的虚函数会覆盖基类的虚函数,并且只有第一个虚表中存放的是真实的覆盖后的地址,其他的虚表中存放的则是一条跳转指令
单个虚拟继承,不带虚函数
- 在派生类对象的存储空间的开始会多一个虚基指针
vbptr
- 在派生类对象的存储空间的布局中,虚基类部分位于最末尾
单个虚拟继承,带虚函数
-
相比于不带虚函数而言,虚基类部分会按照虚函数的规则
-
若派生类有自己的虚函数,则会在派生类对象的开始多一个新的虚函数指针
vfptr
以及一个虚表,该虚表存放派生类自己的虚函数的入口地址
this指针指向对应子对象的位置
多重虚拟继承,不带虚函数
- 派生类对象的存储空间布局是按照继承时的声明顺序
- 派生类只有一个虚基指针,一个虚基表
多重虚拟继承,带虚函数
- 派生类对象的存储空间布局是按照继承时的声明顺序
多重继承,包含虚拟继承以及普通继承
- 派生类对象的存储空间布局是按照继承时的声明顺序,并且在派生类对象的存储空间布局中 普通继承始终位于虚拟继承之前
菱形继承,虚拟继承,不带虚函数
菱形继承,虚拟继承,带虚函数
- 类B 和 类C 分别对于继承的虚基类A的虚表 的合并
&thunk: this-=8; goto C::c
&thunk: this-=32; goto B::b
使用VS: 在 项目 > 属性 > C/C++ > 命令行
处添加以下命令:
/d1 reportAllClassLayout [X]
X可选,代表源文件名字,如 main.cpp,/d1 reportAllClassLayout main.cpp
/d1 reportSingleClassLayoutX
X代表类名,如,/d1 reportSingleClassLayoutA