跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++

C++ 类大小计算详解:内存对齐与虚函数机制

C++ 类大小计算涉及内存对齐、虚函数指针及继承关系。静态成员与成员函数不计入实例大小。空类占 1 字节。有虚函数时增加虚表指针(vptr)。继承时基类成员先布局,再按最大对齐数补齐。虚继承引入额外指针开销。掌握这些规则有助于理解底层内存布局及优化性能。

佛系玩家发布于 2026/3/23更新于 2026/5/1210 浏览
C++ 类大小计算详解:内存对齐与虚函数机制

C++ 类大小计算详解:内存对齐与虚函数机制

这是一个经典的 C++ 面试题,也是理解对象内存布局的关键。很多人直觉认为类的大小等于所有成员变量之和,但实际上编译器会根据内存对齐、虚函数表指针以及继承关系进行自动调整。

内存布局示意图

核心规则速览

在动手计算之前,先明确几个基本原则:

  1. 非静态成员变量是构成类大小的主体。
  2. 静态成员变量存储在数据区,不属于对象实例,sizeof 时不计入。
  3. 成员函数存储在代码段,同样不计入对象大小。
  4. 虚函数:只要类中存在虚函数(包括继承而来的),对象内部就会包含一个虚函数表指针(vptr)。64 位系统通常为 8 字节,32 位为 4 字节。
  5. 内存对齐:为了 CPU 访问效率,成员之间或末尾会有填充字节。
    • 第一个成员偏移量为 0。
    • 后续成员需位于其自身大小整数倍的地址上。
    • 最终类总大小必须是最大成员对齐数的整数倍。
  6. 空类:大小为 1 字节,确保每个对象拥有唯一地址。

详细计算示例

1. 基础情况:空类

class Empty {
    // 没有任何成员
};

虽然看起来什么都没有,但 sizeof(Empty) 的结果是 1 字节。这是为了给对象分配一个独一无二的内存地址,避免不同对象占据同一位置。

2. 只有成员变量(注意对齐)

class Example1 {
    char c; // 1 字节
    int i;  // 4 字节
};

直观上看是 1 + 4 = 5 字节,但实际结果是 8 字节。原因如下:

  • c 从偏移 0 开始,占 1 字节。
  • i 需要 4 字节对齐,所以它不能紧挨着 c(偏移 1),必须跳到偏移 4 的位置。
  • 中间产生了 3 字节的填充。
  • 当前占用:1(c) + 3(填充) + 4(i) = 8 字节。
  • 最大对齐数是 4,8 是 4 的倍数,无需末尾填充。

3. 引入虚函数(vptr 的影响)

class  {
     a;
    {}
};
Base
int
virtual void func()

这里有两个关键点:

  1. int a 占 4 字节。
  2. 因为存在 virtual,编译器会隐式添加一个 vptr(64 位下为 8 字节)。
  3. 对齐问题:vptr 需要 8 字节对齐。a 放在偏移 0~3,vptr 必须从偏移 8 开始。因此 a 后面需要填充 4 字节。
  4. 总大小 = 4(a) + 4(填充) + 8(vptr) = 16 字节。

4. 继承关系

class A {
    int a; // 4
    char b; // 1
    // A 的实际大小:b 后填充 3 字节,A 为 8 字节
};

class B : public A {
    int c; // 4
    char d; // 1
};

派生类 B 的布局逻辑:

  1. 先放置基类 A 的部分:8 字节。
  2. 接着放 c:偏移 8(满足 4 字节对齐),占 4 字节,当前总偏移 12。
  3. 接着放 d:偏移 12,占 1 字节,当前总偏移 13。
  4. 末尾对齐:B 中最大的对齐需求是 4(来自 int)。当前大小 13 不是 4 的倍数,需要在末尾填充 3 字节,使其达到 16。
  5. 结果:16 字节。

5. 特殊情况:虚继承

虚继承用于解决菱形继承问题,通常会在对象中增加额外的指针来定位虚基类子对象。

class A { int x; }; // 4 字节
class B : virtual public A { int y; };

这种情况较为复杂,取决于具体编译器的实现。通常比普通继承多出一个指针的开销(64 位下约 8 字节),用于动态查找虚基类。

总结

计算类大小时,可以遵循这个思路:

  1. 列出所有非静态成员变量。
  2. 检查是否有虚函数或虚继承,加上对应的指针开销。
  3. 应用内存对齐规则:成员间填充 + 末尾补齐。

公式化表达即:类大小 = 非静态成员变量大小之和 + 虚函数/虚继承指针开销 + 内存对齐填充字节。

目录

  1. C++ 类大小计算详解:内存对齐与虚函数机制
  2. 核心规则速览
  3. 详细计算示例
  4. 1. 基础情况:空类
  5. 2. 只有成员变量(注意对齐)
  6. 3. 引入虚函数(vptr 的影响)
  7. 4. 继承关系
  8. 5. 特殊情况:虚继承
  9. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 AI Studio 构建自定义爬虫方案
  • Python Flask Vue 人脸识别实名认证校园论坛及活动报名系统
  • C 语言初阶算法习题实战解析(二)
  • STM32F407 CubeMX HAL 库三环串级 PID FOC 电控算法实现总结
  • QCoder 实战:AI 辅助 Python 数据清洗与可视化
  • CVE-2026-21962 Oracle WebLogic 代理插件漏洞分析与防护
  • AutoGen 多智能体架构:构建软件开发团队智能体
  • 开源模型 Llama3.1 本地部署与实战指南
  • 波士顿动力机器人技术解析:从 Spot 到 Atlas
  • 大规模语言模型从理论到实践:MOSS 与 RLHF 实践
  • Counterfeit-V3.0 Stable Diffusion 模型实战与参数配置指南
  • Visual Studio Code + Maven:Java 项目安装配置与开发指南
  • Java JDK8 时间 API 详解:核心类、格式化与计算
  • Windows Git 安装全流程与配置指南
  • Python 开发环境搭建:Miniconda 安装指南
  • Anything XL 教程:Streamlit 实时预览与生成进度可视化
  • Cursor AI 使用与 Git 版本控制指南
  • 2026 年国内高含金量人工智能认证 TOP8 盘点
  • Kubernetes ResourceList 资源量加减运算工具类
  • Vue 与 C++:前端与系统开发差异

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online