重写,运行时多态的实现,虚函数表

大佬写的https://blog.csdn.net/caoshangpa/article/details/80112673

同类对象共用虚函数表

(对象中不含虚函数表,只有一个指向虚函数表的指针)
在这里插入图片描述

重写后子类虚函数表(有重写,没有新的虚函数)

在这里插入图片描述

重写后子类虚函数表 (没有有重写,有新的虚函数)

在这里插入图片描述

多重继承后子类虚函数表

在这里插入图片描述上图分析:
派生类重写:
virtual void base1_fun1() {}
virtual void base2_fun2() {}
基类虚函数表被重写;

对于派生类自己的虚函数
virtual void derive1_fun1() {}
virtual void derive1_fun2() {}
派生类虚函数表位置:保存到第1个拥有虚函数表的那个基类的后面的。
谁有虚函数表, 谁就放在前面!

当base1没有虚函数时:

在这里插入图片描述
保存到第1个拥有虚函数表的那个基类的后面的。谁有虚函数表, 谁就放在前面!还是正确的

两个基类都没有虚函数表

在这里插入图片描述
现在__vfptr已经独立出来了, 不再属于Base1和Base2!

总结:

由于继承完全拥有父类的所有, 包括数据成员与虚函数表, 所以:把一个继承类强制转换为一个基类是完全可行的。
子类的重写或虚函数 会影响 复制来的父类虚函数表
永远不会影响 父类本身的虚函数表

如果有一个Derive1的指针, 那么:
得到Base1的指针: Base1* pb1 = pd1;
得到Base2的指针: Base2* pb2 = pd1;
得到Base3的指针: Base3* pb3 = pd1;
非常值得注意的是:
这是在基类与继承类之间的转换, 这种转换会自动计算偏移! 按照前面的布局方式!
也就是说: 在这里极有可能: pb1 != pb2 != pb3 ~~, 不要以为她们都等于 pd1!

函数调用

如果不是虚函数, 直接调用指针对应的基本类的那个函数
如果是虚函数, 则查找虚函数表. 	//查的是子类的虚函数表       运行时多态实现原理

为什么父类析构函数要用虚函数:

fa* fa1 = son1;		
//相当于son强转fa,因为fa有的son1都有,所以可以执行
//然后把son把fa覆盖的部分,覆盖到fa1下   就算完成了。
默认的析构函数执行的是fa();
构造时执行fa();
析构时:析构为虚函数,执行~son(),把 ~fa()覆盖;
			析构为普通函数,执行~fa();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值