剑指offer sizeof(空类)

本文探讨了C++中空类的sizeof运算符结果及其在含有虚函数时的变化,同时深入解析了赋值运算符函数的实现细节与注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题1、问:对一个没有任何成员变量和成员函的空类求sizeof,得到什么结果?
答:空类的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该实例的时候,他必须在内存中占用一定的空间,否则无法使用该实例,在VS中,每个空类型的实例占用1字节的空间
如果该类中添加一个构造函数和析构函数,还是1,调用构造函数和析构函数只需要知道函数的地址即可,而这些函数地址与类型相关,与类型的实例无关,编译器也不会因为两个函数而在实例中添加任何额外的信息。
如果把析构函数标记为虚函数,(构造函数不能是虚函数,原因见:http://www.cnblogs.com/lixiaohui-ambition/archive/2012/08/28/2660708.html),c++编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。
题2:赋值运算符函数
注意的四点:1、返回值的类型为该类型的引用,并在函数结束后返回实例自身的引用,才可以连续赋值
2、传入的参数类型声明为常量引用,在赋值运算符函数内不会改变实例的状态
3、要释放自身已有的内存
4、判断传入的参数和当前的实例是不是同一个实例

### C++ 中空类 `sizeof` 为 1 的原因 在 C++ 中,即使一个没有任何成员变量或方法,其 `sizeof` 返回也至少为 1 字节。这是由 C++ 标准规定的,目的是为了满足以下几个需求: #### 1. **对象区分** 如果空类的大小为零,则无法通过指针来区分不同的对象实例。C++ 要求即使是空类的对象也需要有唯一的地址,以便支持多态性和继承机制。因此,编译器会分配至少 1 字节的空间给空类对象,从而确保每个对象都有独立的存储位置[^2]。 #### 2. **内存布局一致性** C++ 型系统的实现依赖于一致的内存模型。对于任何型的对象,都需要有一个有效的内存地址。如果没有最小的非零大小,可能会导致内存管理混乱,尤其是在涉及动态分配 (`new`) 或指针运算的情况下。为此,标准规定了空类的最小尺寸为 1 字节[^1]。 #### 3. **兼容性标准化** C++ 继承自 C,在设计时考虑到了底层硬件架构的兼容性。大多数现代计算机体系结构不允许定义零长度的数据单元,因为这违反了基本的寻址规则。为了避免潜在冲突并保持跨平台的一致行为,C++ 将空类的默认大小设置为 1 字节。 以下是验证这一特性的代码示例: ```cpp class EmptyClass {}; int main() { EmptyClass obj; std::cout << "Size of EmptyClass: " << sizeof(obj) << " bytes" << std::endl; return 0; } ``` 运行此程序的结果将是: ``` Size of EmptyClass: 1 bytes ``` #### 4. **避免未定义行为** 当调用某些函数(如 `memcpy` 或 `memset`)处理对象时,这些函数通常假设目标区域具有有效大小。如果允许空类拥有零字节大小,则可能导致不可预测的行为甚至崩溃。强制设定最低限度的大小有助于规避这些问题[^3]。 --- ### 总结 综上所述,C++ 设计者决定让所有——无论是否为空——都具备至少 1 字节的实际占用空间,主要是出于逻辑严谨性、性能优化以及其他语言特性协同工作的考量。这种做法既保障了程序员能够安全地操作各种复杂数据结构,又维持了高层次抽象层面上的良好语义表达能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值