当前位置: 首页 > 编程笔记 >

C++虚函数的实现机制分析

凤棋
2023-03-14
本文向大家介绍C++虚函数的实现机制分析,包括了C++虚函数的实现机制分析的使用技巧和注意事项,需要的朋友参考一下

本文针对C++的虚函数的实现机制进行较为深入的分析,具体如下:

1、简单地说,虚函数是通过虚函数表实现的。那么,什么是虚函数表呢?
事实上,如果一个类中含有虚函数,则系统会为这个类分配一个指针成员指向一张虚函数表(vtbl),表中每一项指向一个虚函数的地址,实现上就是一个函数指针的数组。

例如下面这个例子:

class Parent
{
public:
 virtual void foo1() { }
 virtual void foo1() { }
 void foo1();
};

class Child1
{
public:
 void foo1() { }
 void foo3();
};

class Child2
{
public:
 void foo1() {}
 void foo2() {}
 void foo3();
};

下面列出了各个类的虚函数表(vtbl)的内容。
Parent类的vtbl:Parent::foo1( )的地址、Parent::foo1( )。
Child1类的vtbl:Child1::foo1( )的地址、Parent::foo1( )。
Child2类的vtbl:Child1::foo1( )的地址、Child2::foo1( )。

2、可以看出,虚函数表既有继承性,又有多态性。每个派生类的vtbl继承了它各个基类的vtbl,如果基类vtbl中包含某一项,则派生类的vtbl中也将包含同样的一项,但是两项的值可能不同。如果派生类覆盖了该项对应的虚函数,则派生类vtbl的该指针先指向重载后的虚函数,没有重载的话,则沿用基类的值。

3、在类对象的内存布局中,首先是该类的vtbl指针,然后才是对象数据。在通过对象指针调用一个虚函数时,编译器生成的代码将先获取对象类的vtbl指针,然后调用vtbl中对应的项。对于通过对象指针调用的情况,在编译期间无法确定指针指向的是基类对象还是派生类对象,或者是哪个派生类的对象。但是在运行期间执行到调用语句时,这一点已经确定,编译后的调用代码能够根据具体对象获取正确的vtbl,调用正确地虚函数,从而实现多态性。

4、分析一下这里的思想所在:
问题的实质是这样,对于发出虚函数调用的这个对象指针,在编译期间缺乏更多的信息,而在运行期间具备足够的信息,但那时已不再进行绑定了,怎么在二者之间做一个过渡呢?
把绑定所需的信息用一种通用的数据结构记录下来,该数据结构可以同对象指针相联系,在编译时只需要使用这个数据结构进行抽象的绑定,而在运行期间将会得到真正的绑定。这个数据结构就是vtbl。可以看到,实现用户所需的抽象和多态需要进行后绑定,而编译器又是通过抽象和多态实现后绑定的。

 类似资料:
  • 本文向大家介绍c++中虚函数的实现详解,包括了c++中虚函数的实现详解的使用技巧和注意事项,需要的朋友参考一下 前言 c++ 分为编译时多态和运行时多态。运行时多态依赖于虚函数,大部分人或许听说过虚函数是由虚函数表+虚函数指针实现的,但,真的是这样吗?虽然 c++ 规范有着复杂的语言细节,但底层实现机制却任由编译器厂商想象。(没准某种特殊的处理器电路结构原生支持虚函数,没准这个处理器压根不是冯纽曼

  • 本文向大家介绍C++ 虚函数和纯虚函数的区别分析,包括了C++ 虚函数和纯虚函数的区别分析的使用技巧和注意事项,需要的朋友参考一下 首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数。 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数,才代表函数没有被实现。 定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函

  • 本文向大家介绍C#虚函数用法实例分析,包括了C#虚函数用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#虚函数用法。分享给大家供大家参考。具体如下: 希望本文所述对大家的C#程序设计有所帮助。

  • 用C语言完全模拟C++虚函数表的实现与运作方式 如果对前面两大节的描述仔细了解了的话,想用C语言来模拟C++的虚函数以及多态,想必是轻而易举的事情了! 前提 但是,话得说在前面,C++的编译器在生成类及对象的时候,帮助我们完成了很多事件,比如生成虚函数表! 但是,C语言编译器却没有,因此,很多事件我们必须手动来完成,包括但不限于: 手动构造父子关系 手动创建虚函数表 手动设置__vfptr并指向虚

  • 本文向大家介绍c++ 构造函数中调用虚函数的实现方法,包括了c++ 构造函数中调用虚函数的实现方法的使用技巧和注意事项,需要的朋友参考一下 我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数。这种调用都是对象已经构建完成的情况。那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: 输出: 0 1 2 也就是说,在构造函数中调用虚函数,调用的是正在构造的类中的虚函

  • 实现分页机制 在本实验中,需要重点了解和实现基于页表的页机制和以页为单位的物理内存管理方法和分配算法等。由于ucore OS是基于80386 CPU实现的,所以CPU在进入保护模式后,就直接使能了段机制,并使得ucore OS需要在段机制的基础上建立页机制。下面比较详细地介绍了实现分页机制的过程。