C++ 多重继承的内存布局和指针偏移

news2024/11/20 12:21:07

在 C++ 程序里,在有多重继承的类里面。指向派生类对象的基类指针,其实是指向了派生类对象里面,该基类对象的起始位置,该位置相对于派生类对象可能有偏移。偏移的大小,等于派生类的继承顺序表里面,排在该类前面的所有的类的数据成员(含虚表指针)所占的空间大小总和。

下面以一个简单的程序为例,揭示有多重继承关系的派生类对象的内存布局:

#include <stdio.h>
#pragma pack(4)
 
class A {
  void foo() {}
};
 
class B {
public:
  virtual void func() {};
private:
  int b;
};
 
class C {
  int c;
};
 
class D : public A, public B, public C {
public:
  void func() override {};
private:
  int d;
};
 
int main(int argc, const char* argv[]) {
  D* pd = new D();
  A* pa = pd;
  B* pb = pd;
  C* pc = pd;
 
  printf("pd=%p, pa=%p, pb=%p, pc=%p\n"
         "sizeof(A)=%zd\n"
         "sizeof(B)=%zd\n"
         "sizeof(C)=%zd\n"
         "sizeof(D)=%zd\n",
      pd, pa, pb, pc,
      sizeof(A), sizeof(B),
      sizeof(C), sizeof(D));
  return 0;
}

注意该程序用 #pragma pack 指令指示数据在内存中按 4 字节来对齐。在 x64 平台上编译执行结果:

$ g++ test.cc -std=c++11
$ ./a.out
pd=0x10c0010, pa=0x10c0010, pb=0x10c0010, pc=0x10c001c
sizeof(A)=1
sizeof(B)=12
sizeof(C)=4
sizeof(D)=20

我们首先来分析这四个类的大小。

A 只有一个普通函数成员 foo,没有任何数据成员,是一个空类,其大小为 1 字节。之所以空类大小不为零,是需要标识类对象在内存中的位置,这 1 字节空间仅作占位用,不代表任何意义。

B 有一个成员变量 int b 和一个虚函数成员 func,其中 b 的大小为 4 字节。 由于存在虚函数,因此 B 类起始位置有一个虚表指针(vptr),在 64 平台上指针的大小为 8 字节。因此 B 的大小为 4 + 8 = 12 字节。

C 仅有一个成员变量 int c,因此其大小也就为 4 字节。

D 继承自A, B, C,它的大小等于 A, B, C 的所有数据成员的大小,加上其自身的数据成员和虚表指针的总的大小:4(b) + 4(c) + 4(d) + 8(vptr) = 20 字节。

注意:在 D 的继承关系链里面,只有基类 B 有虚函数,因此对于 D 对象而言,总体只有一个虚表指针,也就是(B)基类对象中的虚表指针。如果派生类的多个基类都有虚函数,则对应每个有虚函数的基类,在派生类对象里都有一个虚表指针。

因此,对于分析派生类 D 的对象,其内存布局如下:

分析结果与程序运行结果一致。

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

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

相关文章

162.二叉树:填充每个节点的下一个右侧节点指针(力扣)

代码解决 /* // Definition for a Node. class Node { public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NULL), next(NULL) {}Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}Node(int _val, Node* _left, Node* _…

【linux】线程同步和生产消费者模型

线程同步 当我们多线程访问同一个临界资源时&#xff0c;会造成并发访问一个临界资源&#xff0c;使得临界资源数据不安全&#xff0c;我们引入了锁的概念&#xff0c;解决了临界资源访问不安全的情况&#xff0c;对于线程而言竞争锁的能力有强有弱&#xff0c;对于之前就抢到…

在CentOS7下构建TeamSpeak服务器并增加网易云点歌插件

文章目录 部署TeamSpeak创建一个新用户下载并解压服务端下载解压 启动服务端同意许可协议启动与配置开放端口设置开机自启 客户端连接 部署TS3AudioBot并添加网易云插件安装ffmpeg下载TS3AudioBot本体与插件并解压配置TS3AudioBot启动设置开机自启 部署网易云API安装git安装Nod…

【模型架构】学习RNN、LSTM、TextCNN和Transformer以及PyTorch代码实现

一、前言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;模型架构的不断发展极大地推动了技术的进步。从早期的循环神经网络&#xff08;RNN&#xff09;到长短期记忆网络&#xff08;LSTM&#xff09;、Transformer再到当下火热的Mamba&#xff08;放在下一节&a…

Linux|虚拟机|Windows 11 家庭版的Hyper虚拟机服务开启

前言&#xff1a; Windows11的版本是比较多的&#xff0c;但有的时候笔记本预装的可能是家庭版&#xff0c;而家庭版的Windows通常是不支持虚拟机的&#xff0c;也就是说Hyper服务根本就看不到 Windows的程序和功能大体如下&#xff1a; &#x1f197;&#xff0c;那么如何开…

ChaosBlade混沌测试实践

ChaosBlade: 一个简单易用且功能强大的混沌实验实施工具 官方仓库&#xff1a;https://github.com/chaosblade-io/chaosblade 1. 项目介绍 ChaosBlade 是阿里巴巴开源的一款遵循混沌工程原理和混沌实验模型的实验注入工具&#xff0c;帮助企业提升分布式系统的容错能力&…

Nuxt3项目实现 OG:Image

目录 前言 1、安装 2、设置网站 URL 3、启用 Nuxt DevTools 4、创建您的第一个Og:Image a. 定义OG镜像 b. 查看您的Og:Image 5、自定义NuxtSeo模板 a. 定义 NuxtSeo模板 b. 使用其他可用的社区模板 6、创建自己的模板 a. 定义组件 BlogPost.vue b. 使用新模板 c.…

【爱空间_登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

模型 FABE(特性 优势 好处 证据)法则

说明&#xff1a;系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。特性、优势、好处、证据&#xff0c;一气呵成。 1 FABE法则的应用 1.1 FABE法则营销商用跑步机 一家高端健身器材公司的销售代表正在向一家新开的健身房推销他们的商用跑步机。以下…

孩子用的灯什么样的好?安利几款适合孩子用的护眼台灯

随着学生们重返校园&#xff0c;家长和孩子们忙于新学期的准备工作&#xff0c;眼睛健康的考量自然也在其中。这也是为何近年来护眼台灯越来越受到欢迎的原因之一。作为一个长期近视并且日常用眼时间较长的人&#xff0c;我本人对护眼台灯有着长期的使用经历&#xff0c;并对它…

如何创建一个Angular项目(超简单)

1、安装Node.js&#xff08;官网Node.js下载&#xff09; 2、运行node -v和npm -v两条命令&#xff08;检验是否下载成功Node.js&#xff09; 3、npm i -g cnpm --registryhttps://registry.npmmirror.com&#xff08;用npm安装cnpm&#xff0c;将镜像源设置为国内镜像源&…

接入knife4j-openapi3访问/doc.html页面空白问题

大概率拦截器拦截下来了&#xff0c;我们F12看网络请求进行排查 都是 /webjars/ 路径下的资源被拦截了&#xff0c;只需在拦截器中添加该白名单即可"/webjars/**" 具体配置如下&#xff1a; Configuration public class WebConfig implements WebMvcConfigurer {priv…

云端数据提取:安全、高效地利用无限资源

在当今的大数据时代&#xff0c;企业和组织越来越依赖于云平台存储和处理海量数据。然而&#xff0c;随着数据的指数级增长&#xff0c;数据的安全性和高效的数据处理成为了企业最为关心的议题之一。本文将探讨云端数据安全的重要性&#xff0c;并提出一套既高效又安全的数据提…

图像加雾算法的研究与应用

目录 前言 一、图像加雾 1、基于传统方法的雾图合成 2、基于深度学习的雾图合成 3、基于Lightroom Classic实现软件加雾 4、基于深度图的方法实现加雾 二、开源的数据集 三、参考文章 前言 在去雾任务当中&#xff0c;训练和评估去雾算法需要大量的带有雾霾和无雾霾的…

超维小课堂 | 1、Pixhawk硬件平台和PX4固件以及QGC地面站之间的关联和区别

Pixhawk硬件平台和PX4固件以及QGC地面站之间的关联和区别 一、Pixhawk是无人机飞控的硬件平台。 主要集成了相关的单片机芯片和各种传感器的外围电路&#xff0c;因此&#xff0c;可以直观的认为Pixhawk一个由各种硬件模块整合成的硬件平台&#xff0c;类似于集成好的单片机开…

【Qt知识】Qt中的对象树是什么?

在深入Qt编程的世界时&#xff0c;你会频繁遇到一个核心概念——对象树&#xff08;Object Tree&#xff09;。这个概念是Qt框架管理内存、处理事件和组织用户界面元素的基础。 什么是Qt对象树&#xff1f; 如果你的Qt应用程序就像一片茂盛的森林&#xff0c;而这片森林中的每…

CameraProvider启动流程

从Android 8.0之后&#xff0c;Android 引入Treble机制&#xff0c;主要是为了解决目前Android 版本之间升级麻烦的问题&#xff0c;将OEM适配的部分vendor与google 对android 大框架升级的部分system部分做了分离&#xff0c;一旦适配了一个版本的vendor信息之后&#xff0c;之…

炫云亮相第二十届中国国际动漫节国际动漫游戏商务大会!

5月28日-29日&#xff0c;备受瞩目的第二十届中国国际动漫节国际动漫游戏商务大会(iABC2024)在杭州滨江开元名都大酒店隆重召开&#xff01;本届大会以动漫IP为核心&#xff0c;从源头到全系列数字内容&#xff0c;探索创新协同、融合发展、价值转化&#xff0c;并对重点作品和…

校园安保巡逻机器人

2023年8月5日&#xff0c;陕西西安一高校实验室起火冒烟&#xff0c;导致学校化学实验室发生火灾。2022年8月3日&#xff0c;一名歹徒持械闯入江西吉安安福县城的一家私立幼儿园&#xff0c;对着无辜的幼儿行凶伤人&#xff0c;造成3死6伤。 像这样的事故有不断地发生&#xf…

计算机基础学习路线

计算机基础学习路线 整理自学计算机基础的过程&#xff0c;虽学习内容众多&#xff0c;然始终相信世上无难事&#xff0c;只怕有心人&#xff0c;期间也遇到许多志同道合的同学&#xff0c;现在也分享自己的学习过程来帮助有需要的。 一、数据结构与算法 视频方面我看的是青…