C++ 虚函数表及多态内部原理详解

Posted CPP开发者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 虚函数表及多态内部原理详解相关的知识,希望对你有一定的参考价值。

(给CPP开发者加星标,提升C/C++技能)

来源:CSDN -  神技圈子
https://blog.csdn.net/songguangfan/article/details/87898915

C++ 中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。

虚函数表

1、 每一个类都有虚函数列表。

当定义一个有虚函数类的对象时,对象的第一块的内存空间就是一个指向虚函数列表的指针。

在这举个例子

假设我们有这样的一个类:

C++ 虚函数表及多态内部原理详解

如果对代码不理解的话,可以看这幅图就会懂了

注意:虚函数表在最后会有一个结束标志,为1说明还有虚表,为0表示没有虚表了 。(编译器不同,结束标志可能存在差异)C++ 虚函数表及多态内部原理详解

下面,将分别具体说明“无虚函数覆盖”和“有虚函数覆盖”时的虚函数表的情况。

(一)无虚函数覆盖

没有任何的继承,虚函数表如下图

C++ 虚函数表及多态内部原理详解
C++ 虚函数表及多态内部原理详解

根据示意图,编写的代码如下图所示:

C++ 虚函数表及多态内部原理详解
C++ 虚函数表及多态内部原理详解


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

如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。如图所示:

C++ 虚函数表及多态内部原理详解

在这个类的设计中,只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:

C++ 虚函数表及多态内部原理详解

从表中可以看到下面几点,

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

2)没有被覆盖的函数依旧。

这样就会出现虚调用

Base *b = new Derive();

b->f();

C++ 虚函数表及多态内部原理详解
C++ 虚函数表及多态内部原理详解

(三)多重继承(无虚函数覆盖)

下面我们再看看多重继承的情况

C++ 虚函数表及多态内部原理详解

对于子类实例中的虚函数表,是下面这个样子:

C++ 虚函数表及多态内部原理详解

从图上我们可以看到

1)每个父类都有自己的虚表。

2) 子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)

这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

下面我们根据上图来实现一下

C++ 虚函数表及多态内部原理详解
C++ 虚函数表及多态内部原理详解

运行结果如下:

C++ 虚函数表及多态内部原理详解

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

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

下图中,我们在子类中覆盖了父类的f()函数。

C++ 虚函数表及多态内部原理详解

子类虚函数列表如图所示

C++ 虚函数表及多态内部原理详解

三个父类虚函数表中的f()的位置被替换成了子类的函数指针。这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了。

子类虚函数列表访问代码如下:

C++ 虚函数表及多态内部原理详解
C++ 虚函数表及多态内部原理详解

程序运行结果如下所示:


- EOF -


推荐阅读   点击标题可跳转

1、

2、

3、


关注『CPP开发者』

看精选C++技术文章 . 加C++开发者专属圈子

↓↓↓


点赞和在看就是最大的支持❤️

以上是关于C++ 虚函数表及多态内部原理详解的主要内容,如果未能解决你的问题,请参考以下文章

学习攻略C++虚函数表及多态内部原理详解

c++多态及虚函数表内部原理实战详解

C++多态详解

C++多态详解

[C++] 多态详解

[C++] 多态详解