1.实验名称
菱形继承/虚继承和多态的结构
2.实验目的
探寻菱形继承和菱形虚拟继承 且实现多态情况下 类对象的结构
3.实验环境
Vistual Studio2022 x86 Debug
4.实验方法
(1)方法1:打印虚函数表
由于VS的编译器会将虚表的末端设置成0 因此我么可以根据这一特性得到虚表的地址
由此去调用虚函数
(2)方法2:内存窗口查看
通过内存窗口 我们可以知道各个类虚表和变量存放的相对位置
5.实验对象和结果分析
(1)非虚拟继承
我们先来看 方法1得到的结果
根据这个图我们知道不同虚函数地址存放的位置
同时 由于B类对象和D类对象一模一样
我们猜测B类起始位置和D类起始位置相同
我们再根据方法2 也可以得到新的图
由这个图我们可以知道
虚表1指针是存在B对象中A对象部分内
虚表2指针是存在C对象的A对象部分内
虚表1里面存了6个虚函数的地址(0000 0000前面有6个地址)
虚表2里面存了4个虚函数的地址 (0000 0000前面有4个地址)
和我方法1打印的结果刚好符合
可以知道 B::a C::a b c d五个变量的相对位置
因此我们可以将其结构图画出来!
(2)虚拟继承
我们先来看 方法1得到的结果
根据这个图我们知道不同虚函数地址存放的位置
同时 由于B类对象和D类对象一模一样
我们猜测B类起始位置和D类起始位置相同
我们再根据方法2 也可以得到新的图
那么在画图过程中我怎么知道 是虚表指针还是虚基表指针呢?
虚表里面存的是地址 虚基表里面存的是偏移量
由这个图我们可以知道
不同虚表和虚基表的相对存储位置
B的虚表里面存了4个虚函数的地址(0000 0000前面有4个地址)
C的虚表里面存了2个虚函数的地址 (0000 0000前面有2个地址)
A的虚表里面存了2个虚函数的地址 (0000 0000前面有2个地址)
和我方法1打印的结果刚好符合
可以知道 B::a C::a b c d四个变量的相对位置
这个地方为什么说是四个对象?
因为这个地方是虚继承 B和C的公共部分A被拿出来了!
所有它们本质上是共用一个a 所以本质上 B::a和C::a本质上是同一个!
因此我们可以将其结构图画出来!