news 2026/4/24 19:43:43

《你真的了解C++吗》No.017:零大小对象与空基类优化——消失的字节

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《你真的了解C++吗》No.017:零大小对象与空基类优化——消失的字节

《你真的了解C++吗》No.017:零大小对象与空基类优化——消失的字节

导言:虚无的重量

在直觉上,一个没有任何数据成员、没有虚函数的空类(Empty Class),其大小应该是0。然而,如果你在 C++ 中执行sizeof(EmptyClass),你会惊讶地发现结果通常是1

为什么“空”也有重量?这 1 个字节是从哪儿来的?而在继承体系中,这个字节又是如何神秘“消失”的?本章将带你揭开空基类优化(EBO)的秘密。


一、 为什么空类的大小不是 0?

C++ 标准规定:任何独立(Standalone)对象的大小至少为 1 字节。

理由很简单:为了确保同一个类的不同对象在内存中拥有唯一的地址。

想象一下,如果空类的大小是 0:

classEmpty{};Empty a,b;if(&a==&b){/* 它们是同一个对象吗? */}

如果大小为 0,ab的地址就会重叠。当你在数组中存放这些对象时,ptr++将永远停留在原地。为了让new返回唯一的指针,编译器必须为每个空类对象安插一个“占位符”字节。


二、 空基类优化(EBO / EBCO):空间的魔术

虽然独立对象不能是 0 字节,但当一个类作为基类存在时,情况就不同了。

空基类优化(Empty Base Optimization)允许派生类在继承空基类时,不为那个占位符字节分配空间。

1. 物理布局的对比
  • 非优化情况(组合关系)
    如果你在一个类里包含一个空类成员,编译器为了保证成员地址唯一,必须保留那 1 字节(由于内存对齐,甚至可能膨胀到 4 或 8 字节)。
  • 优化情况(继承关系)
    如果你继承自一个空类,编译器会认为基类只是提供了一个“接口”或“类型标签”,它不需要独立的地址。
classEmpty{};// 大小 1// 情况 A:组合 (Composition)classHolder{Empty e;// 占用 1 字节inta;// 占用 4 字节};// sizeof(Holder) 通常是 8 (由于对齐)// 情况 B:继承 (Inheritance) - 触发 EBOclassDerived:publicEmpty{inta;// 占用 4 字节};// sizeof(Derived) 通常是 4!那个 1 字节消失了。

三、 为什么 EBO 在底层开发中如此重要?

你可能会觉得,省下 1 到 4 个字节有什么大不了的?但在泛型编程(如 STL)中,EBO 是极致性能的关键。

典型应用:std::vector的分配器
std::vector通常持有一个分配器对象(Allocator)。大多数分配器是没有任何状态的空类。

  • 如果vector使用组合方式持有分配器,每个vector对象都会白白增大若干字节。
  • 如果vector的内部实现巧妙地继承自分配器,利用 EBO,分配器的空间开销就变成了0

四、 EBO 失效的时刻

EBO 并不是万能的。有一种情况会导致它失效:当派生类的第一个非静态成员变量的类型,恰好也是这个空基类时。

classEmpty{};classBogus:publicEmpty{Empty e;// 第一个成员也是 Emptyinta;};

为了保证基类Empty的地址和成员e的地址不同,编译器此时必须为基类分配空间。在这种布局下,sizeof(Bogus)会再次变大。


五、 C++20 的新方案:[[no_unique_address]]

在 C++20 之前,为了利用 EBO,开发者不得不强行使用“继承”来代替“组合”,这破坏了对象设计的语义(有时明明不是 Is-a 关系,却要写成继承)。

C++20 引入了属性标签,让组合也能享受 EBO:

structHolder{[[no_unique_address]]Empty e;// 告诉编译器:如果不必要,别给它分配地址inta;};// sizeof(Holder) 为 4

总结:空间的艺术

  • 独立空类:必须占 1 字节,以保证地址唯一。
  • 空基类:可以被优化为 0 字节,只要不产生地址冲突。
  • EBO是 C++ 程序员在不破坏抽象的前提下,压榨内存空间的优雅手段。

下一篇预告:聊完了空间的“消失”,我们要聊聊代码的“生成”。在 C++ 中,如果你不写某些函数,编译器会替你写;但它写出来的东西,真的是你想要的吗?

➡️《你真的了解C++吗》No.018:复制操作的隐式生成规则——“大三原则”的底层逻辑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 22:53:33

Jupyter themes美化TensorFlow代码编辑界面

Jupyter Themes 美化 TensorFlow 开发环境:从视觉体验到工程实践 在深度学习项目中,开发者常常需要连续数小时面对屏幕编写和调试模型代码。一个常见的场景是:深夜的实验室里,研究员正盯着 Jupyter Notebook 中泛白的界面逐行检查…

作者头像 李华
网站建设 2026/4/16 23:15:06

YimMenuV2:GTA V模组开发框架深度解析

YimMenuV2:GTA V模组开发框架深度解析 【免费下载链接】YimMenuV2 Unfinished WIP 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenuV2 YimMenuV2作为一款专为GTA V游戏模组开发设计的C20框架,为开发者提供了构建高性能游戏插件的完整技…

作者头像 李华
网站建设 2026/4/18 15:48:26

WAN2.2-14B-Rapid-AllInOne:AI视频生成快速入门指南

WAN2.2-14B-Rapid-AllInOne:AI视频生成快速入门指南 【免费下载链接】WAN2.2-14B-Rapid-AllInOne 项目地址: https://ai.gitcode.com/hf_mirrors/Phr00t/WAN2.2-14B-Rapid-AllInOne 想要在普通电脑上体验专业级AI视频创作吗?WAN2.2-14B-Rapid-Al…

作者头像 李华
网站建设 2026/4/23 7:42:45

springboot中学课堂笔记整理分享系统 小程序

目录已开发项目效果实现截图关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!已开发…

作者头像 李华
网站建设 2026/4/19 6:20:29

错过OpenMP 5.3的AI扩展,你的并行程序将落后3代以上

第一章:错过OpenMP 5.3的AI扩展,你的并行程序将落后3代以上现代高性能计算已全面进入异构并行时代,OpenMP 5.3版本引入的关键AI扩展,标志着CPU-GPU协同编程的重大突破。这些扩展不仅增强了对加速器设备的支持,还为深度…

作者头像 李华
网站建设 2026/4/23 18:42:33

Tina Pro v10.0:专业电路仿真软件的革新突破

Tina Pro v10.0:专业电路仿真软件的革新突破 【免费下载链接】TinaProv10.0中文版README **Tina Pro v10.0 中文版** 是DesignSoft公司力推的一款高效电子设计自动化(EDA)工具,专注于电路仿真领域。它支持包括电路直流分析、瞬态分…

作者头像 李华