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

C++ 如何计算类的大小

C++ 类大小计算需考虑内存对齐、虚函数指针及继承关系。非静态成员变量计入大小,静态成员与成员函数不计入。含虚函数时增加虚表指针(64 位 8 字节)。继承时基类大小叠加派生类成员并满足对齐规则。空类大小为 1 字节。

菩提发布于 2026/3/27更新于 2026/10/2187 浏览
C++ 如何计算类的大小

C++ 如何计算类的大小

在这里插入图片描述

这是一个非常经典的 C++ 面试题。在 C++ 中,计算一个类的大小并不是简单地将成员变量的大小相加,而是涉及内存对齐、虚函数、继承等多个因素的影响。

以下是计算类大小的核心规则和详细步骤:

核心结论速览

  1. 非静态成员变量是影响大小的主体。
  2. 静态成员变量不属于类实例,存在全局数据区,不计入sizeof。
  3. 成员函数存在代码段,不计入sizeof。
  4. 虚函数:只要类有虚函数(无论是 1 个还是多个),类实例中就会有一个虚函数表指针(vptr),在 64 位系统下通常占8 字节,32 位下占4 字节。
  5. 内存对齐:编译器为了提高访问效率,会在成员之间或末尾填充字节,使变量存储在其倍数地址上,并使类总大小是最大对齐数的整数倍。
  6. 继承:
    • 空类大小为 1 字节(为了占位,表示对象存在)。
    • 派生类的大小一般是基类成员 + 派生类新成员,同时也要满足对齐规则。

详细计算步骤与示例

1. 基础计算:空类
class Empty {
    // 没有任何成员
};
  • 大小:1 字节
  • 原因:编译器需要给这个类的对象分配一个独一无二的地址,所以会隐式插入 1 个字节。
2. 只有成员变量(考虑内存对齐)

对齐规则:

  1. 第一个成员在偏移量为 0 的位置。
  2. 后续成员要放到该成员大小的整数倍上。
  3. 最终类的大小要是最大成员大小的整数倍。
class Example1 {
    char c; // 1 字节
    int i;  // 4 字节
};
  • 分析:
    • c 占偏移 0。
    • i 占 4 字节,需要从 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 的大小:对齐到 4,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 字节,对齐后可能 8?
    class B : virtual public A { int y; };
    
    • 结果:通常比普通继承多出一个指针的大小(8 字节),用来定位虚基类子对象。情况比较复杂,取决于编译器实现。

    总结清单

    计算类的大小时,可以按以下清单排查:

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

    简记:

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

    目录

    1. C++ 如何计算类的大小
    2. 核心结论速览
    3. 详细计算步骤与示例
    4. 1. 基础计算:空类
    5. 2. 只有成员变量(考虑内存对齐)
    6. 3. 有虚函数(引入虚表指针)
    7. 4. 继承关系
    8. 5. 特殊情况:虚继承
    9. 总结清单

    更多推荐文章

    查看全部
    • Python 爬虫逆向兼职实战指南
    • 基于 rocketmq-client-python 构建高效 RocketMQ 消息系统
    • Flutter 与 React Native 跨平台移动应用开发技术对比指南
    • Browser-Use + LightRAG Agent:利用 LLM 实现高效网页数据抓取
    • Java 微服务架构设计模式:构建云原生分布式系统
    • C/C++ 核心:函数指针与回调函数实战详解
    • AI 大模型核心知识点梳理与原理分析
    • C++ 继承:面向对象代码复用的核心机制
    • Spring AOP 核心概念与实战入门
    • 多模态大模型核心原理与实战:从 Stable Diffusion 到 Sora
    • VS Code Python 代码格式化插件指南
    • 世界模型发展脉络综述:理解世界与预测未来
    • Flutter Web 刷新后页面回退功能失效的解决方案
    • OpenCLaw 对接本地 Ollama 与 Qwen WebUI 无响应排查
    • 前端核心面试题与实战指南
    • Scratch 与 Python 编程语言核心差异对比
    • 国内 AI 大模型现状与实用工具推荐
    • ClawdBot (OpenClaw) 结合 Discord 机器人部署实战指南
    • 大模型深度解析:定义、架构与伦理挑战
    • AI 产品架构设计:从 0 到 1 搭建信息架构与核心业务流程

    相关免费在线工具

    • 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