美文网首页程序员
C++ 虚函数表

C++ 虚函数表

作者: 石虎132 | 来源:发表于2018-02-19 10:04 被阅读0次

//联系人:石虎 QQ:1224614774 昵称:嗡嘛呢叭咪哄

一、概念

1.多态是由虚函数实现的,而虚函数主要是通过虚函数表(V-Table)来实现的。

如果一个类中包含虚函数(virtual修饰的函数),那么这个类就会包含一张虚函数表,虚函数表存储的每一项是一个虚函数的地址。

 如下图:

   这个类的每一个对象都会包含一个虚指针(虚指针存在于对象实例地址的最前面,保证虚函数表有最高的性能),这个虚指针指向虚函数表。

注:对象不包含虚函数表,只有虚指针,类才包含虚函数表,派生类会生成一个兼容基类的虚函数表。

2.原始基类的虚函数表

原始基类的对象,可以看到虚指针在地址的最前面,指向基类的虚函数表(假设基类定义了3个虚函数)

  如下图:

3.单继承时的虚函数(无重写基类虚函数)

假设现在派生类继承基类,并且重新定义了3个虚函数,派生类会自己产生一个兼容基类虚函数表的属于自己的虚函数表。

  如下图:

Derive class 继承了 Base class 中的三个虚函数,准确的说,是该函数实体的地址被拷贝到 Derive类的虚函数表,派生类新增的虚函数置于虚函数表的后面,并按声明顺序存放。

4.单继承时的虚函数(重写基类虚函数)

现在派生类重写基类的x函数,可以看到这个派生类构建自己的虚函数表的时候,修改了base::x()这一项,指向了自己的虚函数。

  如下图:

5.多重继承时的虚函数(Derived ::public Base1,public Base2)

这个派生类多重继承了两个基类base1,base2,因此它有两个虚函数表。

  如下图:

 它的对象会有多个虚指针(据说和编译器相关),指向不同的虚函数表。

6.多重继承时指针的调整:

  Derive b;

Base1* ptr1 = &b; // 指向 b 的初始地址

Base2* ptr2 = &b; // 指向 b 的第二个子对象

  因为 Base1 是第一个基类,所以 ptr1 指向的是 Derive 对象的起始地址,不需要调整指针(偏移)。

  因为 Base2 是第二个基类,所以必须对指针进行调整,即加上一个 offset,让 ptr2 指向 Base2 子对象。

  当然,上述过程是由编译器完成的。

  Base1* b1 = (Base1*)ptr2;

b1->y(); // 输出 Base2::y()

  Base2* b2 = (Base2*)ptr1;

b2->y(); // 输出 Base1::y()

  其实,通过某个类型的指针访问某个成员时,编译器只是根据类型的定义查找这个成员所在偏移量,用这个偏移量获取成员。由于 ptr2 本来就指向 Base2 子对象的起始地址,所以b1->y()调用到的是Base2::y(),而 ptr1 本来就指向 Base1 子对象的起始地址(即 Derive对象的起始地址),所以b2->y()调用到的是Base1::y()。

7.虚继承时的虚函数表

  虚继承的引入把对象的模型变得十分复杂,除了每个基类(MyClassA和MyClassB)和公共基类(MyClass)的虚函数表指针需要记录外,每个虚拟继承了MyClass的父类还需要记录一个虚基类表vbtable的指针vbptr。MyClassC的对象模型如图

   如下图:

虚基类表每项记录了被继承的虚基类子对象相对于虚基类表指针的偏移量。比如MyClassA的虚基类表第二项记录值为24,正是MyClass::vfptr相对于MyClassA::vbptr的偏移量,同理MyClassB的虚基类表第二项记录值12也正是MyClass::vfptr相对于MyClassA::vbptr的偏移量。

谢谢!!!

相关文章

  • Boolan_C++面向对象高级编程(下)_第二周笔记

    1、 对象模型:关于vptr(虚函数表指针)和vtbl(虚函数表) 1.1 课堂内容总结 (1)class中有虚函...

  • (Boolan) 面向对象高级编程(下)第四周笔记

    一、虚函数表 对C++ 虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)...

  • (Boolan) 面向对象高级编程(下)第四周笔记

    一、虚函数表 对C++虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来...

  • 虚函数表

    虚函数表对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual ...

  • C++虚函数表(多态的实现)

    多态是C++的三大特性之一,是通过虚函数表来实现的。关于虚函数表: 每个含有虚函数的类都有一张虚函数表(vtbl)...

  • 查漏补缺

    C++虚函数: 多态: 静态多态(重载)、动态多态(虚函数) 虚函数 虚函数表:编译器为每个类创建了一个虚函数表...

  • C++虚函数表的内容分析

    这篇文章继续分析C++虚函数表的内容,以及它的工作原理,即用户代码如何访问虚函数表的内容。 下面C++代码定义了一...

  • C++多态——虚函数表vtable

    纯Swift类的函数调用原理,类似于C++的虚函数表 纯Swift类的函数调用,类似于C++的虚函数表,是编译时决...

  • 虚函数

    文章内容转自关于C++中虚函数表存放位置的思考 作者:fuliangcheng 1、虚函数表vtable在Linu...

  • C++虚函数表

    虚函数表 C++中虚函数是通过一张虚函数表(Virtual Table)来实现的,在这个表中,主要是一个类的虚函数...

网友评论

    本文标题:C++ 虚函数表

    本文链接:https://www.haomeiwen.com/subject/xteitftx.html