C++ 虚表起源

本文会让看不见 摸不着的虚表(Vtable),虚指针(Vptr)彻底现行

本文涉及思想:

C++ 面向对象 封装 继承 多态 中的 多态

概念解释:

虚表指针:

这是指向虚表(vtable)的指针,虚表中包含了该类的所有虚函数对应的地址。

虚表:

虚表是一个编译时生成的静态数组,存放在程序的数据段中,包含所有虚函数的地址(不属于类对象,与类对象无关)。每个类有自己的虚表,派生类可以继承基类的虚表并进行修改以反映任何虚函数的覆盖(重写)。

sizeof的严格语义:

A a;

sizeof(A)sizeof(a) 都表示类对象的大小,但它们从语法上指向稍有不同的含义:

sizeof(A):这表示测量 A 类型的对象所占用的内存大小,即类 A 的实例化对象的大小。这是从类型层面进行的测量,表明创建一个该类型的实例所需的字节数。

sizeof(a):这表示测量已经实例化的对象 a 的大小,其中 aA 类的一个实例。这实际上将给出与 sizeof(A) 相同的结果,因为 aA 类型。

如果一个类是空的,那么它占1字节,为了防止类对象重叠.

例如新建10个类,如果大小是0,内存中无论是顺序还是随机,都有概率会使用相同的内存地址

#include <iostream>using namespace std;class A
{
public:
};int main()
{cout << sizeof(A) << endl; // 1return 0;
}

放入一个普通函数,不会改变类对象大小:

类对象的行为属于类的共享资源,存储在代码段中

#include <iostream>using namespace std;class A
{
public:void show(){};//虚函数和普通函数都不占类对象大小
};int main()
{cout << sizeof(A) << endl; // 1return 0;
}

放入一个虚函数,则编译器会为该类创建一个虚指针,64位机器为8字节

#include <iostream>using namespace std;class A
{
public:virtual void show(){}; // 虚函数和普通函数都不占类对象的大小
};int main()
{cout << sizeof(A) << endl; // 64位系统 Vptr占8字节return 0;
}

为了验证上述猜想:

#include <iostream>
using namespace std;
class A
{
public:virtual void show1(){cout << "666" << endl;}virtual void show2(){cout << "666" << endl;}virtual void show3(){cout << "666" << endl;}
};int main()
{A a;cout<<sizeof(A)<<endl;//始终只存在1个虚指针,类对象大小为8字节a.show1();a.show2();a.show3();return 0;
}

无论放几个虚函数,始终只存在一个虚指针

借上面例子->这个虚指针指向一个虚表:

这个虚表就是一个函数指针数组 存放了show1,show2,show3的地址,也是C++实现多态的核心机制

下面我们要在GDB中观察到这4个地址:

g++ -g -o c2 c1.cpp
gdb c2
(gdb) break main
(gdb) run
(gdb) info vtbl a
写了几个虚函数看见几个地址就行

引入C++中两种不同的地址表示方式:

info symbol <> 或 info line <>   通常表示全局地址
info vtbl                                     表示相对于对象实例的地址

 所以可以理解为是两套地址系统,互相不能转换,通过全局的方式观察 show2并不是0x0

这样我们就看见了,也感受到了迷雾中的虚表(Vtable)和虚指针(Vptr)的存在

全剧终.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2981960.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】使用Jenkins + svn + springboot自动构建jar包并自动打包在服务器上运行

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

【南京工程学院×朗汀留学】部分录取案例合集

朗汀留学 X 南京工程学院 作为深耕留学的专业资深团队&#xff0c;朗汀留学成功帮助上千名学生出国留学。 在此我们将南京工程学院的部分留学案例作以总结&#xff0c;以供新生参考。再次恭喜所有 获得理想大学offer的学生们&#xff0c;你们的努力让梦想照进现实。 学校介绍…

2024年51cto视频下载方法

这里教大家如何将自己购买的51cto视频下载到本地 首先要利用一个工具:小白51cto工具 我已经打包好了 小白51cto链接&#xff1a;https://pan.baidu.com/s/1jR1fze51XaYwqhuOtlW7Wg?pwd1234 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 教程开始 0.登录好51…

(三)Servlet教程——Tomcat安装与启动

首先打开浏览器在浏览器地址栏中输入清华大学开源软件镜像站地址&#xff0c;地址如下 https://mirrors.tuna.tsinghua.edu.cn/ 输入地址后回车会出现如下图所示的界面 在该界面找tomcat不是很好找&#xff0c;在搜索框中输入apache然后回车&#xff0c;输入apache后并回车后出…

代码随想录算法训练营第四十六天| LeetCode139.单词拆分

一、LeetCode139.单词拆分 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0139.%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86.html 状态&#xff1a;已解决 1.思路 单词明显就是物品&#xff0c;字符串s明显就是背包&#xff0c;那么问题就变成了物品能不能把背…

java:观察者模式

java&#xff1a;观察者模式 1 前言 观察者模式&#xff0c;又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;他定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时&#xff0c;会通知所…

邂逅JavaScript逆向爬虫-------基础篇之面向对象

目录 一、概念二、对象的创建和操作2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承3.3.1 对象的原型式继承3.3.2 …

Java | Leetcode Java题解之第48题旋转图像

题目&#xff1a; 题解&#xff1a; class Solution {public void rotate(int[][] matrix) {int n matrix.length;// 水平翻转for (int i 0; i < n / 2; i) {for (int j 0; j < n; j) {int temp matrix[i][j];matrix[i][j] matrix[n - i - 1][j];matrix[n - i - 1]…

YOLOv8 训练自己的数据集(20240423)

环境搭建请参考&#xff1a;Win10 搭建 YOLOv8 运行环境&#xff08;20240423&#xff09;-CSDN博客 环境测试请参考&#xff1a;本地运行测试 YOLOv8&#xff08;20240423&#xff09;-CSDN博客 一、使用 YOLOv8 的 coco128 数据集熟悉一下如何训练和预测 1.1、在项目根目录…

二手车交易平台搭建重点,会用到哪些三方服务?

在搭建二手车交易平台时&#xff0c;有几个重点方面需要关注&#xff0c;并且会涉及到一些第三方服务的使用。以下是关键点和可能用到的第三方服务&#xff1a; 一、二手车交易平台搭建重点 用户友好与界面设计&#xff1a;一个成功的二手车交易平台首先需要一个直观、易用且吸…

【软件安装】(十六)双系统Ubuntu22.04引导启动菜单的默认项

一个愿意伫立在巨人肩膀上的农民...... 好学的人总是喜欢在电脑上安装双系统&#xff0c;可是安装好系统之后&#xff0c;就会出现默认启动优先级的苦恼&#xff0c;如果在Bios中设置Windows引导启动为优先启动&#xff0c;那么每次想要进如Ubuntu系统就都需要重新设置Bios。如…

LAMMPS单层石墨烯建模

本文主要介绍两种晶胞建模方式。 一、Z形晶胞 晶胞分析&#xff1a;a1沿水平x轴方向&#xff0c;a2沿垂直y轴方向。石墨烯是二维结构&#xff0c;a3取小于单层石墨烯厚度。假设石墨烯键长L1.421&#xff0c;则a13L&#xff0c;a21.732L&#xff0c;a32L&#xff08;低于3.35即…

CSAPP | Lab2-Bomb Lab详细解析

预备阶段 1.Lab要求 邪恶的邪恶博士在我们班的机器上安放了大量的“二元炸弹”。二进制炸弹是一个由一系列阶段组成的程序。每个阶段都要求你在 stdin 上键入一个特定的字符串。如果你键入了正确的字符串&#xff0c;那么这个阶段就会被拆除&#xff0c;炸弹就会进入下一个阶…

如何利用美国站群服务器通过CN2线路优化中美之间的数据传输?

如何利用美国站群服务器通过CN2线路优化中美之间的数据传输? 随着全球化进程的不断推进&#xff0c;跨国企业和国际市场的拓展对数据传输速度和稳定性提出了更高的要求。特别是对于中美之间的数据传输&#xff0c;由于地理位置遥远和网络环境不同&#xff0c;优化数据传输变得…

数据类型总结

1 引言 在计算机的世界里&#xff0c;数据类型是被人类定义出来的&#xff0c;方便人去更好地理解、辨别数据。计算机只能识别二进制数&#xff0c;不可能要求写代码时&#xff0c;只是输入一些0/1的东西。通过定义数据类型&#xff0c;可以让人和计算机更好地“沟通”&#x…

制氢机远程监控运维方案

制氢机远程监控运维方案 在当今能源转型的大背景下&#xff0c;氢能作为清洁、高效且可再生的能源载体&#xff0c;其重要性日益凸显。而制氢机作为氢能产业链中的关键设备&#xff0c;其稳定运行与高效运维对于保障氢气供应、推动氢能产业健康发展至关重要。在此背景下&#…

spring boot 基础案例【2】对多环境配置的支持更改

教程1 案例教程 案例仓库 在线编程 教程2 基础教程 教程仓库 在线编程 本案例所在的仓库 本案例所在的文档 进入正文 1.文件目录 1. Chapter12Application.java 地址&#xff1a;/chapter1-2/src/main/java/com/didispace/chapter12/Chapter12Application.java package com.…

康谋分享 | aiSim5激光雷达LiDAR模型验证方法(二)

aiSim中的LiDAR是一种基于光线追踪的传感器&#xff0c;能够模拟真实LiDAR发射的激光束&#xff0c;将会生成LAS v1.4标准格式的3D点云&#xff0c;包含了方位角、俯仰角和距离等。 aiSim能够模拟LiDAR单态&#xff08;Monostatic&#xff09;和同轴&#xff08;Coaxial&#…

PC端微信软件如何多开【详细教程】

现在工作中&#xff0c;很多小伙伴会用到两个微信。如何在PC端同时登录多个微信呢&#xff1f;赶快跟着下面的教程学起来吧 1、创建一个txt文本文件 2、输入以下代码并保存 echo offstart "" "复制粘贴微信的目标地址" 需要开几个微信就复制几行exit示例…

UTONMOS:用区块链技术拓展商业边界在哪里?

引言 大约从 2021 年Web 3 这个新概念开始受到风险基金和科技圈的普遍关注。但如果你对过去几年区块链的发展历史足够了解&#xff0c;就应该已经意识到现在的 Web 3 并不是什么新技术&#xff0c;甚至不是旧技术的进步&#xff0c;它只是一个基于区块链技术的宏大构想。 我是…