C++ 虚函数表及多态内部原理详解
Posted CPP开发者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 虚函数表及多态内部原理详解相关的知识,希望对你有一定的参考价值。
(给CPP开发者加星标,提升C/C++技能)
来源:CSDN - 神技圈子 https://blog.csdn.net/songguangfan/article/details/87898915
C++ 中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。
虚函数表
1、 每一个类都有虚函数列表。
当定义一个有虚函数类的对象时,对象的第一块的内存空间就是一个指向虚函数列表的指针。
在这举个例子
假设我们有这样的一个类:
如果对代码不理解的话,可以看这幅图就会懂了
注意:虚函数表在最后会有一个结束标志,为1说明还有虚表,为0表示没有虚表了 。(编译器不同,结束标志可能存在差异)
下面,将分别具体说明“无虚函数覆盖”和“有虚函数覆盖”时的虚函数表的情况。
(一)无虚函数覆盖
没有任何的继承,虚函数表如下图
根据示意图,编写的代码如下图所示:
(二)一般继承(有虚函数覆盖)
如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。如图所示:
在这个类的设计中,只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:
从表中可以看到下面几点,
1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。
2)没有被覆盖的函数依旧。
这样就会出现虚调用
Base *b = new Derive();
b->f();
(三)多重继承(无虚函数覆盖)
下面我们再看看多重继承的情况
对于子类实例中的虚函数表,是下面这个样子:
从图上我们可以看到
1)每个父类都有自己的虚表。
2) 子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)
这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。
下面我们根据上图来实现一下
运行结果如下:
(四)多重继承(有虚函数覆盖)
下面我们再来看看,如果发生虚函数覆盖的情况。
下图中,我们在子类中覆盖了父类的f()函数。
子类虚函数列表如图所示
三个父类虚函数表中的f()的位置被替换成了子类的函数指针。这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了。
子类虚函数列表访问代码如下:
程序运行结果如下所示:
- EOF -
1、
2、
3、
关注『CPP开发者』
看精选C++技术文章 . 加C++开发者专属圈子
↓↓↓
点赞和在看就是最大的支持❤️
以上是关于C++ 虚函数表及多态内部原理详解的主要内容,如果未能解决你的问题,请参考以下文章