C++面试常见问题——12虚函数
虚函数
虚函数的工作原理
虚函数的实现要求对象携带额外的信息,这些信息用于确定运行时调用哪一个虚函数,这一信息具有一种被称为虚函数表指针(vptr)的指针形式。vptr指向一个被称为虚函数表(vtbl)的函数指针数组,每一个包含虚函数的类都关联到一个vtbl。当一个对象调用了一个虚函数,实际被调用的虚函数通过以下步骤确定:找到对象的vptr指向的vtbl,在vtbl中找到对应的函数指针。
虚函数的地址翻译取决于对象的内存地址,而不取决于数据类型(编译器对函数调用的合法性检查依赖于数据类型)。如果一个类包含了虚函数,类及其派生类就会生成一张虚函数表vtable,在类对象地址空间中存储一个该虚函数表的入口,这个入口时构造对象时编译器自动写入的。由于虚函数对象的内存空间包含虚函数表的入口,编译器能通过该入口调用正确的虚函数,因此这个函数的地址就不再由数据类型决定了。对于一个父类对象指针调用虚函数,如果赋父类对象的指针,就调用父类的虚函数;若赋子类对象的指针,就会调用子类的函数。
每当创建一个包含虚函数的类或者从包含虚函数的类中派生的类时,编译器会对该类生成一个虚函数表保存类中所有虚函数的地址,可以将这个虚函数表看成一个函数指针数组。在带有虚函数的类中,编译器会秘密置入一个VPTR,指向这个对象的VTABLE,当构造该派生类对象时,VPTR被初始化指向该派生类的VTABLE。可以认为VTABLE是该类所有对象共有的;而VPTR则是每个类对象独一份的,且在该类对象被构造时被初始化。
通过基类指针做虚函数调用(多态调用)时,编译器静态的插入取得VPTR,并在VTABLE中选取正确的虚函数。
每个类有一个VTABLE,并且该虚函数表对该类的所有实例共享,但类的每个实例都只有一个VPTR。
参考链接:
C++面试常见问题——12虚函数的更多相关文章
- 【C++面试】关于虚函数的常见问题
1.虚函数的代价 1)带有虚函数的每个类会产生一个虚函数表,用来存储虚成员函数的指针 2)带有虚函数的每个类都会有一个指向虚函数表的指针 3)不再是内敛函数,因为内敛函数可以在编译阶段进行替代,而虚函 ...
- C++语言基础(12)-虚函数
一.虚函数使用的注意事项 1.只需要在虚函数的声明处加上 virtual 关键字,函数定义处可以加也可以不加. 2.为了方便,你可以只将基类中的函数声明为虚函数,这样所有子类中具有遮蔽(覆盖)关系的同 ...
- 【校招面试 之 C/C++】第11题 C++ 纯虚函数
1.纯虚函数 成员函数的形参后面写上=0,则成员函数为纯虚函数. 纯虚函数声明: virtual 函数类型 函数名 (参数表列) = 0: class Person { virtual void Di ...
- 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数
1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...
- 以boost::function和boost:bind取代虚函数
转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...
- python 常忘代码查询 和autohotkey补括号脚本和一些笔记和面试常见问题
笔试一些注意点: --,23点43 今天做的京东笔试题目: 编程题目一定要先写变量取None的情况.今天就是因为没有写这个边界条件所以程序一直不对.以后要注意!!!!!!!!!!!!!!!!!!!!! ...
- C++ 复习要点、面试常见问题总结
本文总结一下C++面试时常遇到的问题.C++面试中,主要涉及的考点有: 关键字极其用法,常考的关键字有const, sizeof, typedef, inline, static, extern, n ...
- 为何JAVA虚函数(虚方法)会造成父类可以"访问"子类的假象?
首先,来看一个简单的JAVA类,Base. 1 public class Base { 2 String str = "Base string"; 3 protected vo ...
- C++之虚函数的作用和使用方法
在同一类中是不能定义两个名字相同.参数个数和类型都相同的函数的,否则就是“重复定义”.但是在类的继承层次结构中,在不同的层次中可以出现名字相同.参数个数和类型都相同而功能不同的函数.例如在例12.1( ...
随机推荐
- 「JLOI2012」树
「JLOI2012」树 传送门 不得不说这题的数据是真的水... 我们可以想到很明确的一条思路:枚举每一个点向根节点跳,知道路径和不小于 \(s\),恰好等于 \(s\) 就直接加答案. 跳的过程可以 ...
- ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Aborting operation.
将start-dfs.sh,stop-dfs.sh两个文件顶部添加以下参数 HDFS_NAMENODE_USER=root HDFS_DATANODE_USER=root HDFS_SECONDARY ...
- day2-2循环语句
ECMAScript不存在块级作用域,在循环内部定义的变量也可以在外部访问到 局部变量与全局变量: 1) 使用var操作符定义的变量将成为定义该变量的作用域中的局部变量. 2) 如果在函数中定义变量没 ...
- JS html页面
js窗口置顶 if (window != top) top.location.href = location.href; js打开新窗口 js window.open()弹出窗口参数说明及居中设置 f ...
- MAC97A6检测
- checkbox全选/取消全选
//checkbox全选/取消全选 $(function() { $("#checkAll").click(function() { if(this.checked){ $(&qu ...
- js中for循环(原生js)
1,普通for循环,经常用的数组遍历 var arr = [1,2,3,4,5]; for ( var i = 0; i <arr.length; i++){ console.log(arr[i ...
- 119、Java中String类之通过isEmpty判断是否为空字符串
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 吴裕雄--天生自然PYTHON爬虫:安装配置MongoDBy和爬取天气数据并清洗保存到MongoDB中
1.下载MongoDB 官网下载:https://www.mongodb.com/download-center#community 上面这张图选择第二个按钮 上面这张图直接Next 把bin路径添加 ...
- C#文件过滤器filter---转载
C#文件过滤器filter OpenFileDialog对话框的Filter属性说明: 首先说明一个示例,分析一下Filter属性的构成:“ Excel文件|*.xls ”,前面的“Excel文件”成 ...