当前位置: 首页 > news >正文

c++类对象数据成员和虚函数的内存布局

一直想搞清楚类对象的数据成员和虚函数的内存布局,今天刚好有时间,所以就写了个demo查看了一下具体的内存布局情况(使用的编译器为微软的)。

下面是自己demo的代码:

#include <iostream>
#include <windows.h>//#pragma pack(4)  //影响每个类对象对齐的字节数,默认对齐到8字节
class A
{
public:virtual void Test1() {};int a;
};class B
{
public:virtual void Test2() {};int b;
};class C :public A, public B {
public:virtual void Test1() override{}virtual void Test2() override{}virtual void Test3() {};int c;
};void main()
{C *pC = new C();pC->a = 1;pC->b = 2;pC->c = 3;int size = sizeof(*pC);int sizeA = sizeof(A);int sizeC = sizeof(C);A* pA = pC;B* pB = pC;int sizeA1 = sizeof(*pA);bool bRet = (pB == pC);
}
  • 下面是代码执行的时候内存布局截图:

从截图可以得到以下结果:

  1. 派生类对象C首先包含了基类A对象的数据,然后包含基类B对象的数据,最后才是包含自己的数据成员。

  1. 派生类C中包含了2个虚表,一个虚表是指向基类A中的函数,一个虚表是指向基类B中的函数。类C有2个虚表是因为它派生自两个基类。如果是单继承就只有一个虚表。

还有一个知识点无法从图中得知:如果派生类中包含自己的虚函数,则这个函数会添加到第一个虚表的尾部。

  • 下面是代码执行的时候对象占用内存大小截图:

类A对象会占用的内存大小为16字节:虚表指针8个字节+数据成员a占用4个字节,此时只有12个字节,但是微软编译器默认是对齐到8字节的,所以最终加上字节对齐,整个类A对象占用的内存大小为16字节。

类C对象占用的内存大小为40字节:类A的部分占用16字节+类B的部分占用16字节+数据成员c占用4个字节,此时只有36个字节,根据字节对齐默认为8字节,所以最终加上字节对齐,整个类C占用的内存大小为40字节。

如果将前面代码中的第四行代码“//#pragma pack(4)”的注释去掉(将编译器字节对齐强制设为4字节),此时各个类对象的内存占用大小会发生变化。具体如下:

类A对象会只占用12字节(虚表指针8个字节+数据成员a占用4字节,刚好对齐到4字节),类C对象会占用28字节(类A对象12字节+类B对象12字节+数据成员C占用4字节,刚好对齐到4字节)

对齐到4字节的内存占用大小截图:

  • 下面是将pC(类C对象的地址)赋值给pA(类A指针)和pB(类B指针)以后,pC,pA,pB具体值的截图:

从截图可知:

  1. pA的值和pC的值相等:这是因为类C的继承关系中,类A是第一个基类,所以在类C对象的内存布局中,首先就是类A所占用的部分。

  1. pB的值-pC的值=12字节:这是因为类C的继承关系中,类A是第一个基类,类B是第二个基类,所以在类C对象的内存布局中,类B放在类A的后面,只要把pC的地址加上类A占用的部分(12字节,对齐到4字节)就是pB的地址。

根据上面的结果,我们知道pB和pC虽然指向同一个对象,但是他们的地址值不一样,如果用pB和pC比较会返回true还是false呢?下面是运行截图:

我们发现最终的比较结果为true,这个是因为编译器在比较两个指针的时候,不是简单的对两个地址值进行比较,如果发现两个指针所属的类有继承关系的时候,会先进行转换,然后再比较。

相关文章:

c++类对象数据成员和虚函数的内存布局

一直想搞清楚类对象的数据成员和虚函数的内存布局&#xff0c;今天刚好有时间&#xff0c;所以就写了个demo查看了一下具体的内存布局情况&#xff08;使用的编译器为微软的&#xff09;。下面是自己demo的代码&#xff1a;#include <iostream> #include <windows.h&g…...

Python 模块和包

1. 模块和包 **容器&#xff1a;**列表、元组、字符串、字典等&#xff0c;对数据的封装**函数&#xff1a;**对语句的封装**类&#xff1a;**对方法和属性的封装&#xff0c;即对函数和数据的封装 而模块&#xff08;module&#xff09;就是个程序&#xff0c;一个.py 文件&…...

Java零基础专栏——面向对象

1 面向对象思想1.1 什么是面向对象&#xff1f;2 类和对象2.1 类和对象的理解2.2 类的定义2.3定义类的补充注意事项2.4 对象的使用2.5 练习3 封装3.1 封装思想3.1.1 封装概述3.1.2 封装的步骤3.1.3 封装代码实现3.2 private关键字3.3 练习—private的使用4 构造方法4.1 构造方法…...

离散无记忆与有记忆信源的序列熵

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;information-theory】&#xff0c;需要的朋友们自取。或者公众号【AIShareLab】回复 信息论 也可获取。 文章目录离散无记忆信源的…...

算法该不该刷?如何高效刷算法?

一、算法该不该刷&#xff1f;最近有小伙伴向我咨询一个问题&#xff0c;就是算法该不该刷&#xff0c;该如何刷算法呢&#xff1f;这个问题可谓太大众化了&#xff0c;只要你去某乎、某度搜索一下相关的解答&#xff0c;会有无数种回答&#xff0c;可见这个问题困扰了多少学习…...

Allegro如何在关闭飞线模式下查看网络连接位置操作指导

Allegro如何在关闭飞线模式下查看网络连接位置操作指导 在用Allegro做PCB设计的时候,有时会因为设计需要,关闭飞线显示。 如何在关闭飞线显示模式下查看网络连接的位置,如下图 除了能看到网络连接的点位以外,还能看到器件的pin Number 如何显示出这种效果,具体操作如下 …...

啊哈 算法读书笔记 第 1 章 一大波数正在靠近——排序

目录 排序算法&#xff1a; 时间复杂度&#xff1a; 排序算法和冒泡排序之间的过渡&#xff1a; 冒泡排序 冒泡排序和快速排序之间的过渡&#xff1a; 快速排序 排序算法&#xff1a; 首先出场的是我们的主人公小哼&#xff0c;上面这个可爱的娃就是啦。期末考试完了老…...

Servlet笔记(5):HTTP请求与响应

1、HTTP请求 当浏览器请求网页时&#xff0c;它会向Web服务器发送特定信息&#xff0c;这些信息不能被直接读取&#xff0c;而是通过传输HTTP请求时&#xff0c;封装进请求头中。 有哪些头信息&#xff1f; 头信息描述Accept这个头信息指定浏览器或其他客户端可以处理的 MIME…...

信号的运算与变换

目录 前言 本章内容介绍 信号的运算与变换 相加 相乘 时移 反折 尺度变换 微分&#xff08;差分&#xff09; 积分&#xff08;累加&#xff09; 信号的奇偶求解 信号的实虚分解 合适的例题 1、时移反折 2、时移尺度 3、时移反折尺度 4、反求x(t) 前言 《信号…...

【GO】K8s 管理系统项目9[API部分--Secret]

K8s 管理系统项目[API部分–Secret] 1. 接口实现 service/dataselector.go // secret type secretCell corev1.Secretfunc (s secretCell) GetCreation() time.Time {return s.CreationTimestamp.Time }func (s secretCell) GetName() string {return s.Name }2. Secret功能…...

ESP32 Arduino EspNow点对点双向通讯

ESP32 Arduino EspNow点对点双向通讯✨本案例分别采用esp32和esp32C3之间点对点单播无线通讯方式。 &#x1f33f;esp32开发板 &#x1f33e;esp32c3开发板 &#x1f527;所需库(需要自行导入到Arduino IDE library文件夹中&#xff0c;无法在IDE 管理库界面搜索下载到该库)&am…...

Linux SID 开发指南

Linux SID 开发指南 1 前言 1.1 编写目的 介绍Linux 内核中基于Sunxi 硬件平台的SID 模块驱动的详细设计&#xff0c;为软件编码和维护提供基 础。 1.2 适用范围 内核版本Linux-5.4, Linux-4.9 的平台。 1.3 相关人员 SID 驱动、Efuse 驱动、Sysinfo 驱动的维护、应用开…...

Matlab进阶绘图第2期—线型热图

线型热图由共享X轴的多条渐变直线组成&#xff0c;其颜色表示某一特征值。 与传统热图相比&#xff0c;线型热图适应于X轴数据远多于Y轴&#xff08;条数&#xff09;的情况&#xff0c;可以很好地对不同组数据间的分布情况进行比较&#xff0c;也因此可以在一些期刊中看到它的…...

【Redis中bigkey你了解吗?bigkey的危害?】

一.Redis中bigkey你了解吗&#xff1f;bigkey的危害&#xff1f; 如果面试官问到了这个问题&#xff0c;不必惊慌&#xff0c;接下来我们从什么是bigkey&#xff1f;bigkey划分的类型&#xff1f;bigkey危害之处&#xff1f; 二.什么是bigkey&#xff1f;会有什么影响&#xff…...

C++回顾(一)——从C到C++

前言 在学习了C语言的基础上&#xff0c;C到底和C有什么区别呢&#xff1f; 1.1 第一个C程序 #include <iostream>// 使用名为std的命名空间 using namespace std;int main() {// printf ("hello world\n");// cout 标准输出 往屏幕打印内容 相当于C语言的…...

CRF条件随机场 | 关键原理+面试知识点

😄 CRF之前跟人生导师:李航学习过,这里结合自己的理解,精简一波CRF,总结一下面试中高频出现的要点。个人觉得没网上说的那么复杂,我看网上很大部分都是一长篇先举个例子,然后再说原理。没必要原理其实不难,直接从原理下手更好理解。 文章目录 1、概率无向图(马尔可夫…...

秒懂算法 | 回归算法中的贝叶斯

在本文中,我们会用概率的观点来看待机器学习模型,用简单的例子帮助大家理解判别式模型和生成式模型的区别。通过思考曲线拟合的问题,发现习以为常的损失函数和正则化项背后有着深刻的意义 01、快速理解判别式模型和生成式模型 从概率的角度来理解数据有着两个不同的角度,假…...

用Netty实现物联网01:XML-RPC和JSON-RPC

最近十年,物联网和云计算、人工智能等技术一道,受到业内各方追捧,被炒得火热,甚至还诞生了AIoT这样的技术概念。和(移动)互联网不同,物联网针对的主要是一些资源有限的硬件设备,比如监控探头、烟雾感应器、温湿度感应器、车载OBD诊断器、智能电表、智能血压计等。这些硬…...

腾讯云服务器centos7安装python3.7+,解决ssl问题

使用requests模块访问百度&#xff0c;报错如下&#xff1a; requests.exceptions.SSLError: HTTPSConnectionPool(hostwww.baidu.com, port443): Max retries exceeded with url: / (Caused by SSLError("Cant connect to HTTPS URL because the SSL module is not avail…...

C++【模板STL简介】

文章目录C模板&&STL初阶一、泛型编程二、函数模板2.1.函数模板概念2.2.函数模板格式2.3.函数模板的实例化2.4.模板参数的匹配原则三、 类模板3.1.模板的定义格式3.2.类模板的实例化STL简介一、STL的概念、组成及缺陷二、STL的版本C模板&&STL初阶 一、泛型编程…...

ViGEmBus技术指南:构建跨平台游戏控制器兼容解决方案

ViGEmBus技术指南&#xff1a;构建跨平台游戏控制器兼容解决方案 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 如何解决游戏控制器的跨平台兼容性难题&…...

若依(ruoyi)RuoYiApp版—页面

ruoyiApp中的页面是一个符合vue规范的文件&#xff0c;如果你熟悉vue&#xff0c;这里将非常快速上手。 1.如何新增页面 uni-app中的页面&#xff0c;默认保存在工程根目录下的pages目录下。 每次新建页面&#xff0c;均需在pages.json中配置pages列表&#xff1b;未在pages.js…...

【研报280】汽车轻量化材料研究报告:改性塑料的应用趋势

本报告提供限时下载&#xff0c;请查看文后提示以下仅为报告部分内容&#xff1a;摘要&#xff1a;政策与新能源汽车需求双重驱动下&#xff0c;汽车轻量化成为行业核心发展方向&#xff0c;2026年国内将实施新的乘用车碳排放国标&#xff0c;叠加新能源汽车普遍重于燃油车&…...

3步构建数字记忆堡垒:开源工具GetQzonehistory数据留存全攻略

3步构建数字记忆堡垒&#xff1a;开源工具GetQzonehistory数据留存全攻略 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字时代&#xff0c;我们的生活轨迹日益依赖在线平台&#…...

kprobe函数入口时的汇编跳板执行流程与栈帧机制

kprobe函数入口汇编跳板执行流程与栈帧机制 文章目录kprobe函数入口汇编跳板执行流程与栈帧机制前言环境准备ftrace跳板创建跳板执行流程与栈帧逐行拆解初始状态与安全校验双层栈帧构建&#xff08;CONFIG_FRAME_POINTER&#xff09;通用寄存器保存与C函数参数准备剩余寄存器保…...

手把手教你理解半导体中的电阻优化:polycide与salicide的实战应用

半导体工艺中的电阻优化艺术&#xff1a;深入解析polycide与salicide技术 在28nm以下先进制程中&#xff0c;金属硅化物技术已成为决定芯片性能的关键因素。当我们翻开任何一款现代处理器的版图&#xff0c;polycide和salicide这两种看似相似的工艺&#xff0c;实际上在晶体管的…...

保姆级教程:在Linux上用Flume 1.7.0 + Spark 2.4.7搭建实时日志流处理管道

企业级实时日志处理实战&#xff1a;Flume 1.7.0与Spark 2.4.7深度整合指南 在当今数据驱动的商业环境中&#xff0c;实时日志处理能力已成为企业技术栈的核心竞争力。想象一下电商大促期间每秒数万条的用户行为日志&#xff0c;或是金融交易系统中毫秒级延迟的风控信号处理——…...

Qwen2.5-14B-Instruct开源模型落地:像素剧本圣殿短视频脚本批量生成

Qwen2.5-14B-Instruct开源模型落地&#xff1a;像素剧本圣殿短视频脚本批量生成 1. 项目概述 像素剧本圣殿&#xff08;Pixel Script Temple&#xff09;是一款基于Qwen2.5-14B-Instruct深度微调的专业剧本创作工具。它将顶尖的AI推理能力与8-Bit复古美学完美融合&#xff0c…...

定制化 H 型滑触线:抗温抗腐,高效赋能极端工业场景

【超越极限&#xff0c;安全稳定——为极端环境量身定制的H型滑触线】 在充满挑战的工作环境中&#xff0c;选择恰当的电源输送解决方案不仅是提高效率的关键&#xff0c;更是确保安全与可持续发展的基石。针对高温高湿、极寒或强腐蚀性场所特别设计的H型滑触线系列产品&#x…...

【typst-rs】Typst CLI 入口代码解析

这段代码是 Typst CLI 工具的入口点&#xff08;main.rs&#xff09;&#xff0c;Typst 是一个基于 Rust 的排版系统。让我详细解析这段代码的结构和功能。 模块声明 (1-18行) mod args; mod compile; mod completions; mod deps; mod download; mod eval; mod fonts; mod gree…...