c++ 虚函数 虚函数表 个人理解

参考文章:https://blog.csdn.net/qq_20309055/article/details/79298593

整理一份关于虚函数和继承关系的脑图

前言

C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

动态绑定的实现

在说动态绑定之前,我们需要先了解一下什么叫静态绑定,之前学习单片机的汇编语言的时候,我们知道调用一个子程序,或者是中断处理函数等需要打断当前运行进行跳转的行为叫做CALL(调用),大部分的汇编都是这么写的CALL 后面接的是address,指明了需要执行函数的入口地址。这就叫做静态绑定,在编译之后生成的汇编代码里面直接指定在什么位置我们需要调用什么样的函数。运行的时候都是去固定的位置去执行。

而动态绑定表示,当我们通过类的指针去执行内部的函数的时候,编译器就会知道不能简单的执行静态绑定。 要通过vptr找到vtbl去查找应该执行哪个函数,在表里面找到相应的函数位置去执行,而不是在编译的时候就直接指定好了地址。

如何实现查找一个虚函数在虚函数表的位置?

编译器会按照编译时找到的虚函数的位置而安排在table的相应位置,调用虚函数的时候,编译器就会知道自己之前放的虚函数是放在虚函数的哪一个位置。大致逻辑就是这样,关于动态绑定部分以及虚函数表的搜索部分下次再去查一下,总结一下。

一般继承(有虚函数覆盖)

覆盖父类的虚函数是很显然的事情,不然,虚函数就变得毫无意义。下面,我们来看一下,如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。

                                                                                  

为了让大家看到被继承过后的效果,在这个类的设计中,我只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:

                                       

我们从表中可以看到下面几点

1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置

2)没有被覆盖的函数依旧存在子类的虚表之中

3)父类的虚函数放在子类的前面

多重继承(有虚函数覆盖)

下面我们再来看看,如果发生虚函数覆盖的情况。

下面是对于子类实例中的虚函数表的图:

我们可以看见,三个父类虚函数表中的f()的位置被替换成了子类的函数指针。这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了。体现一个问题就是如果出现多继承的情况那么将会创建父类个数的虚表。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值