跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

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

C++ 类大小计算并非简单累加成员变量,需考虑内存对齐、虚函数表指针及继承结构。非静态成员计入大小,静态成员与函数不计入。空类占 1 字节。含虚函数时增加虚表指针(64 位通常 8 字节)。内存对齐遵循偏移倍数及总大小倍数规则。继承包含基类部分并重新对齐。虚继承引入额外指针开销。掌握这些机制对内存优化至关重要。

AiEngineer发布于 2026/3/29更新于 2026/10/2691 浏览
C++ 类大小计算详解:内存对齐与虚函数

C++ 类大小计算详解

在 C++ 中,计算一个类的大小并不是简单地将成员变量的大小相加,而是涉及内存对齐、虚函数、继承等多个因素的影响。理解这些机制对于内存优化和底层调试至关重要。

核心规则速览

  1. 非静态成员变量是决定大小的主体。
  2. 静态成员变量存在于全局数据区,不属于类实例,sizeof 时不计入。
  3. 成员函数存储在代码段,不占用对象空间,不计入 sizeof。
  4. 虚函数:只要类中有虚函数(包括继承来的),实例中就会包含一个虚函数表指针(vptr)。64 位系统通常占 8 字节,32 位下占 4 字节。
  5. 内存对齐:编译器为了提高访问效率,会在成员间或末尾填充字节,使变量存储在其倍数地址上,且类总大小必须是最大对齐数的整数倍。
  6. 空类:大小为 1 字节,用于保证每个对象都有独一无二的地址。

实战案例解析

1. 基础情况:空类
class Empty {
    // 没有任何成员
};
  • 结果:1 字节
  • 原因:即使没有成员,编译器也需要为对象分配一个唯一的地址,因此隐式插入 1 个字节。
2. 只有成员变量(考虑内存对齐)
class Example1 {
    char c; // 1 字节
    int i;  // 4 字节
};
  • 分析:
    • c 从偏移 0 开始,占 1 字节。
    • i 需要 4 字节对齐,所以必须从偏移 4 开始存放。这意味着 c 后面会有 3 个字节的填充。
    • 当前已占:1 (c) + 3 (填充) + 4 (i) = 8 字节。
    • 最大对齐数是 4,8 是 4 的倍数,无需末尾填充。
  • 结果:8 字节(直觉上的 1+4=5 是错误的)。
3. 引入虚函数(虚表指针)
class Base {
    int a;
    virtual void  {}
};
func
()
  • 分析:
    • int a 占 4 字节。
    • 虚表指针(vptr):64 位系统下占 8 字节。
    • 对齐调整:最大对齐数变为 8(vptr)。a 从偏移 0 开始占 4 字节,为了放置 8 字节的 vptr,需要在 a 后填充 4 字节,使 vptr 从偏移 8 开始。
    • 总大小 = 4 (a) + 4 (填充) + 8 (vptr) = 16 字节。
  • 结果: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
};
  • 分析:
    • 先放入基类 A 的部分:8 字节。
    • 再放派生类 B 的 c:偏移 8(刚好是 4 的倍数),占 4 字节,总偏移 12。
    • 再放 d:偏移 12,占 1 字节,总偏移 13。
    • 对齐收尾:B 中最大对齐数是 4(int),当前总大小 13 不是 4 的倍数,所以末尾填充 3 字节到 16。
  • 结果:16 字节。
5. 特殊情况:虚继承

虚继承用于解决菱形继承问题,编译器实现不同,但通常会增加额外开销。

class A { int x; }; // 4 字节
class B : virtual public A { int y; };
  • 结果:通常比普通继承多出一个指针的大小(8 字节),用于定位虚基类子对象。具体开销取决于编译器实现。

总结清单

计算类的大小时,可以按以下逻辑排查:

  1. 基本大小:列出所有非静态成员变量的大小。
  2. 虚函数检查:如果有 virtual 函数(包括继承来的),加上虚表指针的大小(64 位通常为 8 字节)。
  3. 虚继承检查:如果有虚继承,加上虚基类指针的开销(通常也是 8 字节)。
  4. 内存对齐:
    • 计算每个成员相对于起始地址的偏移,插入填充。
    • 最后让总大小是最大对齐数的整数倍,末尾填充。

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

目录

  1. C++ 类大小计算详解
  2. 核心规则速览
  3. 实战案例解析
  4. 1. 基础情况:空类
  5. 2. 只有成员变量(考虑内存对齐)
  6. 3. 引入虚函数(虚表指针)
  7. 4. 继承关系
  8. 5. 特殊情况:虚继承
  9. 总结清单

更多推荐文章

查看全部
  • Linux 网络基础:局域网通信与跨网段传输
  • AI 在医疗领域的十大应用场景与技术实践
  • 通义千问 Qwen3-14B 本地部署与双模式推理体验
  • AGI 大模型算法岗位面试经验汇总
  • 中小团队低成本搭建项目管理系统:Ubuntu 下 DooTask 私有化部署实战
  • Google Antigravity:Agent 优先的 AI IDE 实战评测
  • Flutter eip55 库鸿蒙适配指南:以太坊地址校验与验证
  • Python 入门实战:3 个练手小项目(含代码)
  • PostgreSQL 哈希与复合分区实践
  • 无人机 RemoteID 合规实战:基于 ArduRemoteID 的开源方案指南
  • C++ 轻量级搜索引擎实战:正/倒排索引构建指南
  • Python 常用库实用清单:从数值计算到深度学习
  • C++ 入门:发展历史、命名空间与输入输出详解
  • 基于LSTM神经网络的学生成绩预测系统:Django与Python实现
  • WebUI LiuMo Batch:AIGC 工作流批量生成平台解析
  • AI 变现误区解析:为何掌握工具不等于获得收益
  • 开源 RemoteID 方案:无人机身份识别与合规部署指南
  • 英伟达 GTC 2026 发布 Rubin 架构与推理芯片,AI 智能体时代来临
  • Z-Image Turbo LoRA 微调实战指南:基于 ai-toolkit 的训练流程
  • Buzz 离线语音转文字工具安装与使用指南(含 Whisper 模型)

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • 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