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

Posted 太原师院计算机系分团委

tags:

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

点击蓝字

关注我们



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

虚函数表




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

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

在这举个例子

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



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

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

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

注意:虚函数表在最后会有一个结束标志,为1说明还有虚表,为0表示没有虚表了。(编译器不同,结束标志可能存在差异)



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



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

01
无虚函数覆盖
没有任何的继承,虚函数表如下图:

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

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

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

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

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


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

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


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

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


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

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

1

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

2

没有被覆盖的函数依旧。


这样就会出现虚调用:

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

Base *b = new Derive();

b->f();

下面我们用一个示例代码来看一下:

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

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


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

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


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

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


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


从图上我们可以看到:

1

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

2

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

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

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

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

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

运行结果如下:

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



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


子类虚函数列表如图所示:



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


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

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

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

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

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

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

程序运行结果如下所示:



程序讲解:



END







来源:网络

编辑:杨迦南

责编:宗禹含

审核:张宇堃

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

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

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

C++多态详解

C++多态详解

[C++] 多态详解

[C++] 多态详解