C/C++杂记:深入虚表结构

1. 虚表与“虚函数表”

在“C/C++杂记:虚函数的实现的基本原理”一文中曾提到“虚函数表”的概念,只是为了便于理解,事实是:虚函数表并不真的独立存在,它只是虚表(virtual table)中的一部分内容。例:

从图中可已看出,虚表除了包含虚函数指针,还包含其它一些信息(如:RTTI信息、偏移值等)。

顺便介绍一下gcc的-fdump-class-hierarchy选项,它可以用于输出C++程序的虚表结构(在当前目录下生成一个.class文件),例:

2. 虚表结构

一个虚表包含以下几个部分:

其中:

  • 橙色线框中的内容仅限于虚拟继承的情形(若无虚拟继承,则无此内容),虚拟继承的讨论已超过了本文的范围,暂且忽略。
  • “offset to top”是指到对象起始地址的偏移值,只有多重继承的情形才有可能不为0,单继承或无继承的情形都为0。
  • “RTTI information”是一个对象指针,它用于唯一地标识该类型。(注:本系列博文后续会有详细讨论。)
  • “virtual function pointers”也就是我们之前理解的虚函数表,其中存放着虚函数指针列表。

前一节的示例是单继承的示例,下面列出了一个多继承的示例:

从中可以看到:D的虚表中包含两个虚表结构,第一个也称之为“主虚表”(primary virtual table),另一个虚表又称之为“次虚表”(secondary virtual table)。

简单地概括一下:一个含有虚函数(无论是其本身的,还是继承而来的)的类,可以有一个主虚表和多个次虚表,主虚表和次虚表构成一个虚表组(virtual table group)。

3. 参考

Itanium C++ ABI

时间: 2024-08-05 11:31:12

C/C++杂记:深入虚表结构的相关文章

【转载】C/C++杂记:深入虚表结构

原文:C/C++杂记:深入虚表结构 1. 虚表与“虚函数表” 在“C/C++杂记:虚函数的实现的基本原理”一文中曾提到“虚函数表”的概念,只是为了便于理解,事实是:虚函数表并不真的独立存在,它只是虚表(virtual table)中的一部分内容.例: 从图中可已看出,虚表除了包含虚函数指针,还包含其它一些信息(如:RTTI信息.偏移值等). 顺便介绍一下gcc的-fdump-class-hierarchy选项,它可以用于输出C++程序的虚表结构(在当前目录下生成一个.class文件),例: 2.

虚表结构与虚继承内存对象模型

最近看了下Inside C++里面讲的对虚继承层次的对象的内存布局,发现在不同编译器实现有所区别.因此,自己动手探索了一下.结果如下: 首先,说说GCC的编译器. 它实现比较简单,不管是否虚继承,GCC都是将虚表指针在整个继承关系中共享的,不共享的是指向虚基类的指针. class A { int a; virtual ~A(){} }; class B:virtual public A{ virtual ~B(){} virtual void myfunB(){} }; class C:virt

C++杂记:运行时类型识别(RTTI)与动态类型转换原理

运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. 静态类型的情形 C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例: #include <typeinfo> #include <cassert> struct B {} b, c; struct D : B {

【转载】C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理

原文:C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理 运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. 静态类型的情形 C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例: #include <typeinfo> #include <cassert>

C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理

运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. 静态类型的情形 C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例: #include <typeinfo> #include <cassert> struct B {} b, c; struct D : B {

揭开C++类中虚表的“神秘面纱”

C++类中的虚表结构是C++对象模型中一个重要的知识点,这里咱们就来深入分析下虚表的在内存中的结构. C++一个类中有虚函数的话就会有一个虚表指针,其指向对应的虚表,一般一个类只会有一个虚表,每个虚表有多个”插槽”,每个插槽存放一个虚函数的地址.插槽中的内容可以被覆盖,子类如果重写了父类中的虚函数,则插槽中对应位置的数据被覆盖.虚表存放的是虚函数地址,不管该虚函数是public还是private的.光文字说明不太形象,下面上一张虚表结构的示例图: 从图中看出,虚表指针确实是指向虚表结构的,这个虚

实例解析C++虚表

OS:Windows 7 关键字:VS2012,C++,VTable,虚表 1.创建一个Win32控制台应用程序代码如下: #include "stdafx.h" #include <string> #include <iostream> class A { public: virtual std::string AName(){return "A";} }; class B { public: virtual std::string BNa

深入理解C++对象模型

C++对象模型是比较重要的一个知识点,学习C++对象的内存模型,就可以明白C++中的多态原理.类的初始化顺序问题.类的大小问题等. 1 C++对象模型基础 1.1 C++对象中都有哪些东东 C++对象中包括以下内容: 静态常量 成员变量 成员函数 虚函数 纯续函数 ... 以下是一个对象的定义: class Base { static int b_s; public: void function() { } virtual void v_function() { cout << "B

Javascript 创建正则表达式的两种方法

负载均衡,这应该是一个永恒的话题,也是一个十分重要的话题.毕竟当网站成长到一定程度,访问量自然也是会跟着增长,这个时候, 一般都会对其进行负载均衡等相应的调整. 在这篇文章中,我们会介绍一些能够确保系统硬件和软件正常工作的方法,这些方法能够避免潜在的会导致生产环境下线或钱财损失的问题发生. 报告 Linux 进程统计信息 http://www.cnblogs.com/mesrjre/  你可以使用 mpstat 单独查看每个处理器或者系统整体的活动,可以是每次一个快照或者动态更新. 首先,修饰方