虚函数

虚函数的工作原理

虚函数的实现要求对象携带额外的信息,这些信息用于确定运行时调用哪一个虚函数,这一信息具有一种被称为虚函数表指针(vptr)的指针形式。vptr指向一个被称为虚函数表(vtbl)的函数指针数组,每一个包含虚函数的类都关联到一个vtbl。当一个对象调用了一个虚函数,实际被调用的虚函数通过以下步骤确定:找到对象的vptr指向的vtbl,在vtbl中找到对应的函数指针。

虚函数的地址翻译取决于对象的内存地址,而不取决于数据类型(编译器对函数调用的合法性检查依赖于数据类型)。如果一个类包含了虚函数,类及其派生类就会生成一张虚函数表vtable,在类对象地址空间中存储一个该虚函数表的入口,这个入口时构造对象时编译器自动写入的。由于虚函数对象的内存空间包含虚函数表的入口,编译器能通过该入口调用正确的虚函数,因此这个函数的地址就不再由数据类型决定了。对于一个父类对象指针调用虚函数,如果赋父类对象的指针,就调用父类的虚函数;若赋子类对象的指针,就会调用子类的函数。

每当创建一个包含虚函数的类或者从包含虚函数的类中派生的类时,编译器会对该类生成一个虚函数表保存类中所有虚函数的地址,可以将这个虚函数表看成一个函数指针数组。在带有虚函数的类中,编译器会秘密置入一个VPTR,指向这个对象的VTABLE,当构造该派生类对象时,VPTR被初始化指向该派生类的VTABLE。可以认为VTABLE是该类所有对象共有的;而VPTR则是每个类对象独一份的,且在该类对象被构造时被初始化。

通过基类指针做虚函数调用(多态调用)时,编译器静态的插入取得VPTR,并在VTABLE中选取正确的虚函数。

每个类有一个VTABLE,并且该虚函数表对该类的所有实例共享,但类的每个实例都只有一个VPTR。

参考链接:

  1. C++中虚函数工作原理和(虚)继承类的内存占用大小计算

C++面试常见问题——12虚函数的更多相关文章

  1. 【C++面试】关于虚函数的常见问题

    1.虚函数的代价 1)带有虚函数的每个类会产生一个虚函数表,用来存储虚成员函数的指针 2)带有虚函数的每个类都会有一个指向虚函数表的指针 3)不再是内敛函数,因为内敛函数可以在编译阶段进行替代,而虚函 ...

  2. C++语言基础(12)-虚函数

    一.虚函数使用的注意事项 1.只需要在虚函数的声明处加上 virtual 关键字,函数定义处可以加也可以不加. 2.为了方便,你可以只将基类中的函数声明为虚函数,这样所有子类中具有遮蔽(覆盖)关系的同 ...

  3. 【校招面试 之 C/C++】第11题 C++ 纯虚函数

    1.纯虚函数 成员函数的形参后面写上=0,则成员函数为纯虚函数. 纯虚函数声明: virtual 函数类型 函数名 (参数表列) = 0: class Person { virtual void Di ...

  4. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  5. 以boost::function和boost:bind取代虚函数

    转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...

  6. python 常忘代码查询 和autohotkey补括号脚本和一些笔记和面试常见问题

    笔试一些注意点: --,23点43 今天做的京东笔试题目: 编程题目一定要先写变量取None的情况.今天就是因为没有写这个边界条件所以程序一直不对.以后要注意!!!!!!!!!!!!!!!!!!!!! ...

  7. C++ 复习要点、面试常见问题总结

    本文总结一下C++面试时常遇到的问题.C++面试中,主要涉及的考点有: 关键字极其用法,常考的关键字有const, sizeof, typedef, inline, static, extern, n ...

  8. 为何JAVA虚函数(虚方法)会造成父类可以"访问"子类的假象?

      首先,来看一个简单的JAVA类,Base. 1 public class Base { 2 String str = "Base string"; 3 protected vo ...

  9. C++之虚函数的作用和使用方法

    在同一类中是不能定义两个名字相同.参数个数和类型都相同的函数的,否则就是“重复定义”.但是在类的继承层次结构中,在不同的层次中可以出现名字相同.参数个数和类型都相同而功能不同的函数.例如在例12.1( ...

随机推荐

  1. 06-常见的RAID技术

    目录 06-常见的RAID技术 参考 RAID基本概念 RAID数据组织形式 RAID数据保护方式 RAID0 RAID1 RAID5 RAID6 混合RAID - RAID 10 06-常见的RAI ...

  2. Java入门笔记 00-前言&目录

    前言:这本笔记记录的是Java基础部分的学习内容,大部分内容总结性的,包括: ---01 Java基础语法 ---02 数组 ---03 面向对象 ---04 异常处理 ---05 多线程 ---06 ...

  3. IDEA 解决 Maven 依赖冲突的高能神器,这一篇够不够?

    ​ 1.何为依赖冲突 Maven是个很好用的依赖管理工具,但是再好的东西也不是完美的.Maven的依赖机制会导致Jar包的冲突.举个例子,现在你的项目中,使用了两个Jar包,分别是A和B.现在A需要依 ...

  4. Linux - 监控工具Conky

    主题Harmattan,https://www.jianshu.com/p/5c8d4a1f4c91,这个主题在deepin linux下有黑框背景,因为是伪透明,所以选择黑色背景的主题即可

  5. (踩过的坑)使用Github Page搭建个人博客

    最近需要搭建一个网站,作为导航网址,但是自己的域名备案还要等上几天,就想着有没有别的办法来搭建一个公网可以访问的网站. Github Page的话是一个github个人主页,完全适合用来搭建普通网站. ...

  6. 解决Hibernate配置文件不在SRC文件夹下获取Session方法

  7. Java--API解读之Method Summary

    参考来源:Java 中静态方法 实例方法 具体方法区别与联系 JAVA Method Summary网页 * Static Method :"静态方法",直接引用,无需创建对象: ...

  8. Nvidia发布更快、功耗更低的新一代图形加速卡

    导读 不出意外的,Nvidia在其举行的Supercomputing 19大会上公布了很多新闻,这些我们将稍后提到.但被忽略的一条或许是其中最有趣的:一张更快.功耗更低的新一代图形加速卡. 多名与会者 ...

  9. Eclipse中java代码注释变成乱码的问题

    今天在查看曾经写过的代码时发生了一件很是让人头疼的事: 我写的所有注释全部都变成了了乱码,曾经刚入门时也是经常遇到类似的问题,解决起来很快,每天可能都会在工作空间里看到,但是随着时间的推移,写代码的规 ...

  10. CSS - 定位(position),难点

    元素的定位属性主要包括定位模式和边偏移两部分. 1. 边偏移 边偏移属性 描述 top 顶端偏移量,定义元素相对于其父元素上边线的距离 bottom 底部偏移量,定义元素相对于其父元素下边线的距离 l ...