c+多态的本质:编译器维护了类型信息同时插入了解释执行机制
Calling a virtual function is slower than calling a non-virtual function for a couple of reasons: First, we have to use the *__vptr to get to the appropriate virtual table. Second, we have to index the virtual table to find the correct function to call. Only then can we call the function. As a result, we have to do 3 operations to find the function to call, as opposed to 2 operations for a normal indirect function call, or one operation for a direct function call. However, with modern computers, this added time is usually fairly insignificant.
Also as a reminder, any class that uses virtual functions has a __vptr, and thus each object of that class will be bigger by one pointer. Virtual functions are powerful, but they do have a performance cost.
https://www.learncpp.com/cpp-tutorial/125-the-virtual-table/
Because for virtual functions linking was not done at compile time. So, what happens when a call to virtual function is executed ,i.e.
Steps are as follows,
- vpointer hidden in first 4 bytes of the object will be fetched
- vTable of this class is accessed through the fetched vPointer
- Now from the vTable corresponding function’s address will be fetched
- Function will be executed from that function pointer
https://thispointer.com/how-virtual-functions-works-internally-using-vtable-and-vpointer/
A late-binding process involves the following activities:
1)Compiler adds a hidden vPtr member to the class, and generates one unique vtable for the class.
At compilation time, when compiler sees the definition of a class with virtual methods, it will build a virtual table (vtable) for the class, which is an array of function pointers to the implementations of all the virtual methods, and add a hidden data member vPtr to the class definition as the FIRST data member.
Now suppose the methods of classes in Fig. 1 (Hi, Hi1, Hi2, Hi3) are all virtual functions. The memory footprint of an object of class Derived becomes:
pDerived
pBase1 pBase2 pBase3
+----+-------------+-------+---------+-------+----------+----------+
|vptr| a1 | vptr2 | a2 | vptr3 | a3 | a |
+----+-------------+-------+---------+-------+----------+----------+
0 4 104 108 208 212 312 412
Fig. 2. Memory footprint of a polymorphic type object
As you can see in the memory footprint, if you use a Base2 pointer to receive a Derived object, for example, this pointer will point to memory offset 104 as pBase2 does.
Note that each Derive object will have its own memory footprint, with the same structure but in different memory locations. However, the vPtrs will all be pointing to the same method implementations, in other words, the vPtr2 of two instances will contain the same address.
The derived-class and the first base class shares the same vPtr, which points to their shared merged vtable (see following section “Inheritance of Base-class vPtrs” for details). The rest of the base classes have their own vPtrs.
Note that no matter how complicated the inheritance hierarchy is, a function pointer in the vtable always points to the latest/lowest implementation of the virtual function in the inheritance hierarchy.
2)Compiler generates code to do dynamic binding using the vtable.
At compilation time, when compiler sees a call to a virtual method thourgh a pointer (pBase2->Hi2( )), it knows that the address of the function is only known at run time, so it will not try to find the implementation of the function. Instead, it knows that the pointer (pBase2) will be pointing to a vPtr at run time. So it generates code to go through the vPtr to find the vtable (whose composition is already know from the type of the pointer), and go to a certain entry of that vtable, fatch that function pointer, and make the call.
3)At run time, when an object is created out of this class definition, its vPtr member will be assigned the address of the class’s vtable.
http://www.referencecode.org/2013/02/c-advanced-tutorial-vptr-and-vtable.html
c+多态的本质:编译器维护了类型信息同时插入了解释执行机制的更多相关文章
- 当我们有多个类 继承同一个父类 这时候使用多态时候 可以使用该父类的类型做引用 不需要将object做引用
当我们有多个类 继承同一个父类 这时候使用多态时候 可以使用该父类的类型做引用 不需要将object做引用
- 初识JAVA(【面向对象】:pub/fri/pro/pri、封装/继承/多态、接口/抽象类、静态方法和抽象方法;泛型、垃圾回收机制、反射和RTTI)
JAVA特点: 语法简单,学习容易 功能强大,适合各种应用开发:J2SE/J2ME/J2EE 面向对象,易扩展,易维护 容错机制好,在内存不够时仍能不崩溃.不死机 强大的网络应用功能 跨平台:JVM, ...
- Java编程思想学习笔记——类型信息
前言 运行时类型信息(RTTI:Runtime Type Information)使得我们可以在程序运行时发现和使用类型信息. Java在运行时识别对象和类的信息的方式: (1)一种是RTTI,它假定 ...
- 《Java编程思想》笔记14.类型信息
运行时类型信息使得你可以在运行时发现和使用类型信息,主要有两种方式: "传统的"RTTI,它假定我们在编译时已经知道了所有的类型: "反射"机制,它允许我们在运 ...
- Java类型信息(RTTI和反射)
要想在IT领域站得住脚,必须得不断地学习来强化自己,但是学过的技术不实践很容易便被遗忘,所以一直都打算开个博客,来记录自己学的知识,另外也可以分享给有需要的人! 最近在学习反射,为了更好地理解反射,就 ...
- 【JavaSE】运行时类型信息(RTTI、反射)
运行时类型信息使得你可以在程序运行时发现和使用类型信息.--<Think in java 4th> **** 通常我们在面向对象的程序设计中我们经常使用多态特性使得大部分代码尽可能地少了解 ...
- 你好,C++(4)2.1.3 我的父亲母亲:编译器和链接器 2.1.4 C++程序执行背后的故事
2.1.3 我的父亲母亲:编译器和链接器 从表面上看,我是由Visual Studio创建的,而实际上,真正负责编译源代码创建生成可执行程序HelloWorld.exe的却是Visual Studi ...
- Java 编程思想 Chapter_14 类型信息
本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最 ...
- 类型信息(RTTI和反射)——RTTI
运行时类型信息可以让你在程序运行时发现和使用类型信息. 在Java中运行时识别对象和类的信息有两种方式:传统的RTTI,以及反射.下面就先来说下RTTI. 1.RTTI: RTTI:在运行时,识别一个 ...
随机推荐
- docker image 镜像导入导出
docker image save -o webv6.tar techcn/noble.web:v6docker image load -i webv6.tar -q
- Ansible14:Playbook条件语句
目录 简介 when关键字 1. when基本使用 2. 比较运算符 3. 逻辑运算符 条件判断与tests 判断变量 判断执行结果 判断路径 判断字符串 判断整除 其他tests 条件判断与bloc ...
- CentOS7 下 yum 安装 Docker CE
前言 Docker 使用越来越多,安装也很简单,本次记录一下基本的步骤. Docker 目前支持 CentOS 7 及以后的版本,内核要求至少为 3.10. Docker 官网有安装步骤,本文只是记录 ...
- C++17 新特性之 std::optional(上)
最近在学习 c++ 17 的一些新特性,为了加强记忆和理解,把这些内容作为笔记记录下来,有理解不对的地方请指正,欢迎大家留言交流. 引言 在介绍之前,我们从一个问题出发,C++ 的函数如何返回多个值? ...
- Oulipo 子串查找
题目描述 思路 使用哈希值表示较长串的子串的值,直接比较哈希值是否相等 代码 #include <cstdio> #include <cstring> using namesp ...
- Python 3 + Selenium 3 简单入门学习示例 126邮箱登录
这是一个很多基础演示的书上的例子,但是一般按照这些书上的代码可能都不能成功登录.也许是网易修改了126的页面导致的吧,下面给出最新的能够work的版本 from selenium import web ...
- 在Eclipse中使用Beyond Compare做为比较工具
1.下载org.eclipse.externaltools-Update-0.8.9.v201003051612.zip插件包 接下来,要下载Beyond Compare的插件,http://beyo ...
- DELL OptiPlex 7050M黑苹果纪录
准备工作: 主机:OptiPlex 7050 Micro Desktop Computer 镜像:黑果小兵 macOS Catalina 10.15.1 安装过程: 大体的安装过程,就Dell品牌而言 ...
- element-UI级联选择器(Cascader)获取label值 ,this.$refs['新组件名'].currentLabels 在2.7版本给移除了,新的解决方法。
原文参考:https://blog.csdn.net/lijiabinbbg/article/details/97396812 遇到的新的问题是如果设置了ref,那么v-model绑定的值不会动态更新 ...
- 编写可维护的JavaScript-随笔(五)
事件处理 当事件触发时,事件对象(event对象)会作为回调参数传入事件处理程序中,event对象包含所有和事件相关的信息 function handleClick(event){ var popup ...