C++静态多态与动态多态的实现原理剖析

Posted 白龙码~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++静态多态与动态多态的实现原理剖析相关的知识,希望对你有一定的参考价值。

文章目录

多态

一、静态多态的实现原理

静态多态主要借助模板和重载。在编译期间,编译器通过类型来实例化模板或者选择合适的重载。因此,静态多态在编译期间完成

二、动态多态的实现原理

①当基类拥有虚函数成员,那么基类本身的大小就不再是成员变量占用的内存,而是多出了一个指针,该指针指向了一个函数指针数组,数组中存放了基类虚函数的地址。(也就是说,含有虚函数的对象的前四个字节是一个指针

这里的函数指针数组称为虚函数表,简称虚表(vftable),指向它的指针称为虚函数表指针,简称虚表指针(vfptr)

②派生类会在继承基类成员变量的同时拷贝一份基类的虚表。如果派生类重写了基类的虚函数,那么派生类就会在它的虚表中将该虚函数原来的地址改成重写后的虚函数的地址。同时,派生类自己的虚函数也会按照声明次序依次被添加到虚表的最后。

注:在多继承的情况下,有几个基类含有虚函数,派生类的内部就有几个虚表,它自己的虚函数添加在第一张虚表的最后

(windows+VS2019+x86环境下,虚表以nullptr作末尾)

③出于多态构成条件的考虑,仅仅在编译时通过指针类型和引用类型来判断调用哪一个函数是不行的,必须在运行时通过查看指针指向的对象或引用的实体来判断函数的调用。

注:虚函数和普通成员函数一样,都是存放在代码区。虚表在VS下也是存放在代码段的,一个类的所有对象都共用一张虚表

1、虚表的创建时机

虚表在编译时期构建,虚表指针在对象调用构造函数之前指向虚表(具体是在初始化列表之前)。

此外,派生类的虚表需要二次写入,即:将基类和派生类的虚表进行合并。

也就是说,在构造一个派生类时,需要进行以下步骤:

  1. 让基类的虚表指针指向基类的虚表。
  2. 调用基类构造函数。
  3. 让派生类的虚表指针指向二次写入后的派生类的虚表。到这一步为止,多态的条件就已经具备了!
  4. 调用派生类的构造函数。

2、多态的必要条件

  1. 被调用的函数必须是虚函数,并且在派生类中,该虚函数必须被重写
  2. 必须通过基类的指针或引用来调用虚函数。

以上是关于C++静态多态与动态多态的实现原理剖析的主要内容,如果未能解决你的问题,请参考以下文章

C++多态底层剖析

C++多态底层剖析

C++多态底层剖析

9-3:C++多态之多态的实现原理之虚函数表,虚函数表指针静态绑定和动态绑定

C++多态 --- 多态实现原理简析

探索C++对象模型