0
点赞
收藏
分享

微信扫一扫

c++关于虚表的一些笔记


文章目录

  • ​​1、虚函数表指针​​
  • ​​2、多态构成的条件​​
  • ​​3、重载、重写、重定义 三者区别​​
  • ​​4、继承与虚函数​​
  • ​​5、单继承中的虚函数表​​
  • ​​无虚函数覆盖​​
  • ​​有虚函数覆盖​​
  • ​​6、单继承中的虚函数表​​
  • ​​无虚函数覆盖​​
  • ​​有虚函数覆盖​​
  • ​​参考​​


看《深度探索c++对象模型》的时候对虚表有了点疑惑,正好网上有些文章解除了这个疑惑,记录一下

1、虚函数表指针

在64位操作系统下当我们计算包含虚函数的类大小时,我们会发现不管类中有几个虚函数,类的大小都会比没有虚函数时类的大小大8,这是因为存了一个指向虚表的指针,大小为8字节。
对象中的这个指针我们叫做虚函数表指针,虚函数指针指向的这个表叫虚函数表简称虚表,虚表中存的是虚函数的地址

c++关于虚表的一些笔记_子类图1 类代码


c++关于虚表的一些笔记_子类_02图2 对象模型


2、多态构成的条件

  • 必须通过父类的指针或者引用调用虚函数
  • 父类的函数必须是虚函数,且子类必须对父类的虚函数进行重写

3、重载、重写、重定义 三者区别

c++关于虚表的一些笔记_虚函数_03

4、继承与虚函数

在构造子类前会先构造父类,而在构造父类的时候,通过this指针看到如下图左所示,虚函数表中存的父类中的三个虚函数的地址,而在构造子类的时候,可以看到如下图右所示,父类中的虚函数在子类中被重写的两个虚函数将父类的虚函数覆盖了,这就是多态父类指针保存子类地址却可以通过父类指针访问子类成员的原因
c++关于虚表的一些笔记_c++_04
当我们在子类中对父类的虚函数重写后,当父类去调用该虚函数的时候,就会访问虚表,然而虚表中存放的是已经被子类覆盖的子类的函数,所以就会转去调用子类中的重写的虚函数。
c++关于虚表的一些笔记_c++_05
其实子类的虚函数是在虚表中的,只不过从监视器的角度看不到,因为从监视器的角度__vfptr的成员始终属于父类的成员。

5、单继承中的虚函数表

无虚函数覆盖

虚函数按照其声明顺序放于表中;
父类的虚函数在子类的虚函数前面;
c++关于虚表的一些笔记_虚函数表_06

有虚函数覆盖

覆盖的fun1()函数被放到了虚函数表中原来父类虚函数的位置
没被覆盖的函数依旧
c++关于虚表的一些笔记_虚函数表_07

6、单继承中的虚函数表

无虚函数覆盖

每个父类都有自己的虚表
子类的成员函数被放到第一个父类的表中(所谓第一个父类是按照声明顺序来判断的)------>这样做是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数
c++关于虚表的一些笔记_虚函数表_08
子类实例中的虚函数表如下图所示:
c++关于虚表的一些笔记_子类_09

有虚函数覆盖

只要子类中重写的父类的虚函数都会覆盖
没被覆盖的函数依旧
c++关于虚表的一些笔记_虚函数表_10
子类虚函数表如下:
c++关于虚表的一些笔记_虚函数_11

举报

相关推荐

0 条评论