怎么计算一个类的大小 (C++)

怎么计算一个类的大小 (C++)

怎么计算一个类的大小 (C++)


文章目录


图文版

在这里插入图片描述

文字版

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

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

核心结论速览

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

详细计算步骤与示例

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

对齐规则:

  1. 第一个成员在偏移量为0的位置。
  2. 后续成员要放到该成员大小的整数倍上。
  3. 最终类的大小要是最大成员大小的整数倍。
classExample1{char c;// 1字节int i;// 4字节};
  • 分析
    • c 占偏移0。
    • i 占4字节,需要从4的倍数(偏移4)开始存。因此,在 c 后面会有3个字节的填充
    • 此时已占:1© + 3(填充) + 4(i) = 8字节。
    • 最大对齐数是4,8是4的倍数,无需末尾填充。
  • 结果8字节(而不是直觉上的 1+4=5)。
3. 有虚函数(引入虚表指针)
classBase{int a;virtualvoidfunc(){}};
  • 分析
    • 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. 继承关系
classA{int a;// 4char b;// 1// 实际A的大小:对齐到4,b后面填充3字节,A为8字节};classB:publicA{int c;// 4char d;// 1};
  • 分析
    • 先放基类A的部分:8字节。
    • 再放派生类B的 c:偏移8(刚好是4倍数),占4字节,总偏移12。
    • 再放 d:偏移12,占1字节,总偏移13。
    • 对齐收尾:B中最大对齐数是4(int),当前总大小13不是4的倍数,所以末尾填充3字节到16。
  • 结果16字节
5. 特殊情况:虚继承

虚继承涉及虚基类指针或类似机制(编译器实现不同,但通常会增加额外开销),用来解决菱形继承问题。

classA{int x;};// 4字节,对齐后可能8?classB:virtualpublicA{int y;};
  • 结果:通常比普通继承多出一个指针的大小(8字节),用来定位虚基类子对象。情况比较复杂,取决于编译器实现。

总结清单

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

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

简记:

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

总结

这篇文章是作者搜集大量面经和资料这里出来的。感谢你的支持
作者wkm是一名中国矿业大学(北京) 大一的新生,希望得到你的关注
如果可以的话,记得一键三联!

Read more

Python `for` 循环完全指南(含用例)

Python for 循环完全指南 for 循环是 Python 中最核心的迭代结构,它能够遍历任何可迭代对象(如列表、元组、字符串、字典、集合、文件对象等),并对每个元素执行指定的操作。与其他语言(如 C 的 for (i=0; i<n; i++))不同,Python 的 for 更接近“foreach”风格,专注于遍历序列或集合中的元素,语法简洁且功能强大。 本文将系统讲解 for 循环的基本语法、常用场景,并通过杨辉三角打印和数独求解器两个综合案例,展示 for 循环在实际编程中的灵活应用。 1. 基本语法与常用场景 1.1 语法结构 for 变量

By Ne0inhk
Python 识别携程中文验证码(95%正确率)并自动登陆携程+图灵图像验证码识别平台

Python 识别携程中文验证码(95%正确率)并自动登陆携程+图灵图像验证码识别平台

这两天有一个业务需求,需要登陆不同的携程账号获取订单信息,但是由于携程有验证码检测机制,而且是个中文验证码比较难识别,试了几家人工打码平台,要么贵,要么延时高,要么没办法24小时运行。最后总算让我找到一个可以通过机器识别出来的API接口,准确率超级高而且延迟只有0.03s左右。(不算上传图片的时间) 首先看一下携程验证码长啥样。。。 携程验证码分为小图和大图部分,小图部分如下:      大图部分的样子如下:   原理是要先识别小图的文字,然后点击到大图对应文字的正确位置。 这里借助了图灵验证码识别平台,不是人工打码的,所以识别很快,准确率也挺高: 在线图片验证码识别平台-图像验证码识别打码平台-图片验证码打码平台-图灵 官网网址:http://fdyscloud.com.cn 进入图灵验证码识别平台,点击中文类型:   可以看到图灵识别平台提供的几个中文识别模型。我们这里需要用到的就是 中文通用类型 和 图片识别类型9。分别点进去,会告诉你对应的模型ID和接口的调用方式。  我们也可以直接在网站上先上传图片测试一下该模型的识别效果,如下图:  可以看到效果是

By Ne0inhk
Qwen-3 微调实战:用 Python 和 Unsloth 打造专属 AI 模型

Qwen-3 微调实战:用 Python 和 Unsloth 打造专属 AI 模型

虽然大家都忙着在 DeepSeek 上构建应用,但那些聪明的开发者们却悄悄发现了 Qwen-3 的微调功能,这可是一个隐藏的宝藏,能把通用型 AI 变成你的专属数字专家。 通过这篇文章,你将学到如何针对特定用途微调最新的 Qwen-3 模型。无论是刚刚踏入 AI 领域的初学者,还是经验丰富的 AI 工程师,这篇文章都有适合你的内容。 Qwen3 很快就成为了大多数开发者的首选。它之所以如此受欢迎,是因为它在编码、数学、通用能力等竞争性评估中获得的基准分数。 这些基准分数超过了主要的 LLM,包括 DeepSeek-R1、o1、o3-mini、Grok-3 和 Gemini-2.5-Pro 等模型。此外,小 MoE 模型 Qwen3–30B-A3B 在激活参数数量上是 Qwen-32B 的 10 倍,甚至一个像

By Ne0inhk
【零基础入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】

【零基础入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】

🌈 个人主页:十二月的猫-ZEEKLOG博客 🔥 系列专栏: 🏀《PyTorch科研加速指南:即插即用式模块开发》-ZEEKLOG博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光  目录 1. 前言 2. 字典 2.1 字典的创建 2.1.1 大括号+直接赋值 2.1.2 大括号+字典推导式 2.1.3 dict+关键字参数 2.1.4 dict+元组列表 2.1.5 dict+zip方法 2.1.6 dict+fromkeys方法 2.2 字典的访问 2.

By Ne0inhk