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( ...
随机推荐
- 计算机基础,Python - 回调函数,使用装饰器注册回调函数
1. 参考: https://en.wikipedia.org/wiki/Callback_(computer_programming) https://developer.mozilla.org/e ...
- Java 笔试题
有一些还是存在问题,欢迎大家一起探讨. 在Java类中,使用以下( )声明语句来定义公有的int型常量MAX. A. public int MAX = 100; B. final int MAX = ...
- python 静态方法,类方法,类下面的函数区别
@clssmenthod(类方法) 与 @staticmethod(静态方法) 与类下面的函数的区别: 1.@classmethod修饰的方法def name(cls)需要通过cls参数传递当前类本身 ...
- C# Stream篇(三) -- TextWriter 和 StreamWriter---转载
C# Stream篇(三) -- TextWriter 和 StreamWriter TextWriter 和 StreamWriter 目录: 为何介绍TextWriter? TextWriter的 ...
- Spring Cloud 从入门到入门
参考:https://blog.csdn.net/hellozpc/article/details/83692496 参考:https://www.fangzhipeng.com/spring-clo ...
- 小程序中data数据的处理方法总结
wxml代码: <view class="container"> <view wx:for="{{list}}" wx:key="t ...
- redis集群配置文件
bind xxx.xxx.xxx.xxx 绑定redis服务器网卡IP,默认为127.,即本地回环地址.这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接.如果bind选项为空的 ...
- C#用SQLDMO操作数据库----转载
C#用SQLDMO操作数据库 sqldmo.dll是随sql server2000一起发布的.sqldmo.dll自身是一个com对象 sqldmo(sql distributed managemen ...
- CSS 常用操作
1.对齐 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...
- 第2节 storm路由器项目开发:8 - 9、集群监控软件ganglia的安装和使用
Ganglia监控Hadoop集群的安装部署 详情请参见 http://boendev.iteye.com/blog/1750615 一. 安装环境 CentOS6.5x86_64 安装gmetad的 ...