福建建设人才市场官方网站爱做的小说网站吗
2026/1/26 5:56:51 网站建设 项目流程
福建建设人才市场官方网站,爱做的小说网站吗,手机论坛,做钓鱼网站教程视频《你真的了解C吗》No.017#xff1a;零大小对象与空基类优化——消失的字节 导言#xff1a;虚无的重量 在直觉上#xff0c;一个没有任何数据成员、没有虚函数的空类#xff08;Empty Class#xff09;#xff0c;其大小应该是 0。然而#xff0c;如果你在 C 中执行 si…《你真的了解C吗》No.017零大小对象与空基类优化——消失的字节导言虚无的重量在直觉上一个没有任何数据成员、没有虚函数的空类Empty Class其大小应该是0。然而如果你在 C 中执行sizeof(EmptyClass)你会惊讶地发现结果通常是1。为什么“空”也有重量这 1 个字节是从哪儿来的而在继承体系中这个字节又是如何神秘“消失”的本章将带你揭开空基类优化EBO的秘密。一、 为什么空类的大小不是 0C 标准规定任何独立Standalone对象的大小至少为 1 字节。理由很简单为了确保同一个类的不同对象在内存中拥有唯一的地址。想象一下如果空类的大小是 0classEmpty{};Empty a,b;if(ab){/* 它们是同一个对象吗 */}如果大小为 0a和b的地址就会重叠。当你在数组中存放这些对象时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)会再次变大。五、 C20 的新方案[[no_unique_address]]在 C20 之前为了利用 EBO开发者不得不强行使用“继承”来代替“组合”这破坏了对象设计的语义有时明明不是 Is-a 关系却要写成继承。C20 引入了属性标签让组合也能享受 EBOstructHolder{[[no_unique_address]]Empty e;// 告诉编译器如果不必要别给它分配地址inta;};// sizeof(Holder) 为 4总结空间的艺术独立空类必须占 1 字节以保证地址唯一。空基类可以被优化为 0 字节只要不产生地址冲突。EBO是 C 程序员在不破坏抽象的前提下压榨内存空间的优雅手段。下一篇预告聊完了空间的“消失”我们要聊聊代码的“生成”。在 C 中如果你不写某些函数编译器会替你写但它写出来的东西真的是你想要的吗➡️《你真的了解C吗》No.018复制操作的隐式生成规则——“大三原则”的底层逻辑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询