侯捷老师(二)P17对象模型,类继承结合虚函数时 底层所发生的事情(虚指针,虚表,虚函数,多态,动态绑定,虚机制 指的都是同一件事情)

内容来自:https://www.bilibili.com/video/av19151507/?p=17
在这里插入图片描述
B继承A,C继承B,C包含有A和B的数据,B包含有A的数据。

虚指针(vptr):对于第一个指针,只要class里有虚函数,数据里就会包含有一个指针,无论多少个虚函数都只有一个指针,所以用sizeof(A)测试A的大小时 会比无虚函数的A多4个字节(32为系统)。

继承的是父类数据 和其函数的调用权,父类有虚函数,子类一定有,也包括那根指针。
对于ABC三个类,一共有8个函数,4个虚函数,4个非虚函数。

虚表(vtbl):虚指针所指的那个表就是虚表,虚表里放的都是函数指针,指向虚函数所在的位置。
A有两个虚函数,所以虚表有两个虚指针。
B继承自A,有两个虚函数,重写了其中一个虚函数,还是两个,所以虚表有两个虚指针。
C继承自B,有两个虚函数,重写了其中一个虚函数,还是两个,所以虚表有两个虚指针。

对象调用虚函数时 底层所发生的的调用顺序:使用new C时便会得到图中的那个虚指针p,这个指针不是直接指向内存空间(传统调用就是直接跳转到那个地址,叫静态绑定),而是先指向一个虚表,虚表里放的才是虚函数的真正内存位置(动态绑定,这是面向对象的设计的关键点)。
上面的流程可以用如下C代码展示:
在这里插入图片描述
首先通过对象的虚指针p找到虚表,然后找到虚表里第n个对应的虚函数的地址,传入参数p(对于传入的这个p,我感觉有点this的效果)。其中n为虚函数的真实地址所在虚表中的位置,也是程序员写的虚函数的顺序0,1,2。。。

编译器在编译调用call时,分两种考虑,静态绑定和动态绑定。动态绑定需要满足三个条件:

  1. 通过指针调用
  2. 指针up-cast,向上造型
  3. 调用虚函数

虚函数的这种用法也叫 多态polymorph

虚指针,虚表,虚函数,多态,动态绑定,虚机制 指的都是同一件事情

举例说明
设计power point,画图形状的类。
抽象出一个类叫 shape, 子类可以有square、rectangle、circular、ellipse等
在这里插入图片描述

list<A*>myList; 用父类创建指针容器,指针可以指向任何子类型,也叫up-cast(向上造型)
其中draw函数为 “画” 这个动作,父类声明,子类重写,所以设计成虚函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值