C++虚函数表小记

最近在读C++ primer plus,看到了关于虚函数表的部分,觉得应该记录一下。

C++只是规定了虚函数应该如何做,但是具体的实现是编译器来负责的。通常编译器是通过向对象添加一个隐藏的成员来操作虚函数,这个隐藏的成员是一个指向数组的指针,这个数组的内容是方法的地址。这个数组通常叫做“虚表”(virtual function table)。这个虚表托管的是这个类所有虚函数的地址。例如,一个基类的对象包含一个指向这个类所有虚函数地址的数组的指针。如果派生类重写了虚函数,则派生类对象的虚表中相应的地址就变成重写后函数的地址。如果派生类没有重写虚函数,则虚表中的地址不变。如果派生类提供了一个新的虚函数,则它的地址会被添加到虚表中。

  当你调用虚函数时,程序就会根据虚表地址去相应的虚表中去查找虚函数,获得虚函数的地址后调用虚函数。

可以看下图帮助理解。

但是,使用虚函数在内存和执行速度上还是有一些成本的。主要在如下几方面:

1、每一个对象的大小会因为要保存虚函数的地址而相应增加一些。

2、对于每一个类,编译器要创建一个虚函数地址表

3、对于每一个虚函数的调用,需要额外的步骤去查询虚表来获得地址。

时间: 2024-11-13 18:10:10

C++虚函数表小记的相关文章

单继承与多继承中的虚函数表和虚函数指针

首先,我们了解一下何为单继承,何为多继承?? 单继承:一个子类只有一个直接父类. 多继承:一个子类有两个或多个直接父类. 单继承中的虚函数表分析: 示例程序: #include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virt

C++ 虚函数表解析

转自陈浩的博客 前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. 关于虚函数的使用方法,我在这里不做过多的阐述.大家可以看看相关的C++的书籍.在这篇文章中,我只想从虚函数的实现

C++虚函数表剖析

关键词:虚函数.虚表,虚表指针,动态绑定,多态 一.概述 为了实现C++的多态,C++使用了一种动态绑定的技术. 这个技术的核心是虚函数表(下文简称虚表).本文介绍虚函数表是怎样实现动态绑定的. 二.类的虚表 每一个包括了虚函数的类都包括一个虚表. 我们知道,当一个类(A)继承还有一个类(B)时.类A会继承类B的函数的调用权.所以假设一个基类包括了虚函数,那么其继承类也可调用这些虚函数,换句话说,一个类继承了包括虚函数的基类.那么这个类也拥有自己的虚表. 我们来看下面的代码. 类A包括虚函数vf

C++ 虚函数表解析(转)

转自:http://blog.csdn.net/haoel 前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. 关于虚函数的使用方法,我在这里不做过多的阐述.大家可以看看相关的C

C++学习之虚函数表及调用规范

在支付工具想做社交,即时通讯工具想做app市场,英语字典想做新闻社交的今天,创造这些怪象的公司要求程序员懂得更多几乎是理所当然的,毕竟现在大家什么都想做.这不,正值招聘季,实验室的几位学长也是一直在讨论各种问题,发现对于C++语言而言,问的最多的还是虚函数表和STL. STL的考点至少是实用的,哪怕要求你读过源码,也并不过分,毕竟知根知底才能更好地应用.但要求程序员掌握对象模型着实拎不清,因为这几乎用不到,远没有在设计模式上投入时间实在,或许它们最希望的是拿批发价招语言专家... 我已经近2年没

类虚函数表原理实现分析(当我们将虚表地址[n]中的函数替换,那么虚函数的实现就由我们来控制了)

原理分析 当调用一个虚函数时, 编译器生成的代码会调用 虚表地址[0](param1, param2)这样的函数. 已经不是在调用函数名了. 当我们将虚表地址[n]中的函数实现改为另外的函数, 虚函数的实现就由我们来控制了. 实验 根据虚表原理, 实验一下修改自己程序的虚函数表项地址. 使编译器生成的代码执行一个虚函数A时, 执行的是我们自己定义的非虚函数B. 知识点 * 使用union赋值, 绕过编译器函数与变量强转赋值的限制 * 类成员函数指针的执行 * 修改和恢复自己的代码段属性 * 虚函

c++ 输出虚函数表内容

class Base{ public: virtual void f(){cout<<"Base::f"<<endl;} virtual void g(){cout<<"Base::g"<<endl;} virtual void h(){cout<<"Base::h"<<endl;} }; typedef void (*Fun)(void); int main(){ Base

C++中3种多态实现机制之虚函数表

上期我们简单的讲解了利用RTTI来实现多肽,这期我们就来聊聊利用虚函数的方法来实现多肽. 1.什么是虚函数 在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体}:,实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数 2.实现多肽的条件 简单的说就是:基类的指针或引用指向子类对象,当子类中成员函数和基类成员函数:函数名相同,参数列表相同,返回值相同,并且基类该函数为虚函数时,基类

《COM原理与应用》题外话——C++虚函数表和delete this

delete this看起来非常的奇怪,我记得在<C++ Primer>中提到过delete this,但是我已经忘了在哪了,也一直没有找到(因为没有电子版,所以一直没找到~).<C++ Primer>中提到的是在析构函数中使用delete this会造成析构函数的无限调用,最终造成栈溢出.我也在网上看了一些,很多人觉得不该使用delete this,因为会引起一些问题.但是delete this也挺有用处的,就和goto语句一样,不应该被一棍子打死(goto语句其实怪好用的:-D