C++空类的大小

本文探讨了C++中空类的实际大小并非为0的原因及其背后的设计考量,并通过实例展示了不同编译器下空类及含有空类成员的类的实际大小。
部署运行你感兴趣的模型镜像

本文中所说是C++的空类是指这个类不带任何数据,即类中没有非静态(non-static)数据成员变量,没有虚函数(virtual function),也没有虚基类(virtual base class)。
直观地看,空类对象不使用任何空间,因为没有任何隶属对象的数据需要存储。然而,C++标准规定,凡是一个独立的(非附属)对象都必须具有非零大小。换句话说,

C++空类的大小不为0

为了验证这个结论,可以先来看测试程序的输出。

#include <iostream>
using namespace std;

class NoMembers
{
};

int main()
{
    NoMembers n;  // Object of type NoMembers.
    cout << "The size of an object of empty class is: "
         << sizeof(n) << endl;
}

输出:

The size of an object of empty class is: 1

C++标准指出,不允许一个对象(当然包括类对象)的大小为0,不同的对象不能具有相同的地址。这是由于:

  • new需要分配不同的内存地址,不能分配内存大小为0的空间
  • 避免除以 sizeof(T)时得到除以0错误

故使用一个字节来区分空类。

值得注意的是,这并不代表一个空的基类也需要加一个字节到子类中去。这种情况下,空类并不是独立的,它附属于子类。子类继承空类后,子类如果有自己的数据成员,而空基类的一个字节并不会加到子类中去。例如,

class Empty {};
struct D : public Empty {int a;};

sizeof(D)为4。

再来看另一种情况,一个类包含一个空类对象数据成员。

class Empty {};
class HoldsAnInt {
    int x;
    Empty e;
};

在大多数编译器中,你会发现 sizeof(HoldsAnInt) 输出为8。这是由于,Empty类的大小虽然为1,然而为了内存对齐,编译器会为HoldsAnInt额外加上一些字节,使得HoldsAnInt被放大到足够又可以存放一个int。

参考资料
1. http://www.stroustrup.com/bs_faq2.html#sizeof-empty
2. https://msdn.microsoft.com/en-us/library/f42z47h2.aspx
3. http://en.cppreference.com/w/cpp/language/sizeof
4. Effective C++, Third Edition, Scott Meyers著, 侯捷译

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

### C++空类的概念 在 C++ 中,空类是指没有任何成员变量和成员函数的类。尽管它看似简单甚至无意义,但在实际开发中却有其独特的用途。 #### 空类的定义 空类可以通过如下方式定义: ```cpp class EmptyClass {}; ``` 即使该类不包含任何数据成员或方法,编译器仍会为其分配一定的内存空间以区分不同的对象实例[^1]。 #### 空类的主要特性 1. **默认构造函数** 即使未显式声明,默认情况下编译器会为每个空类提供一个隐式的默认构造函数。 2. **大小非零** 尽管空类没有成员变量,但它仍然占用一定字节的空间(通常是 1 字节),这是为了确保不同对象之间的地址唯一性。 3. **继承支持** 空类可以作为基类被其他类继承。这使得它可以用于实现某些设计模式中的标记接口功能。 4. **多态行为** 如果为空类添加虚函数,则可以使其实现动态绑定并表现出多态特征。 #### 使用场景分析 - **标记角色** 当需要某种类型的标识而不需要额外的数据存储时,可以用作标签来辅助模板元编程或者策略模式的设计。 - **减少耦合度** 利用空类模拟 Java 接口的功能,在 C++ 中创建轻量级抽象层从而降低模块间的依赖程度。 - **优化性能** 结合 CRTP (Curiously Recurring Template Pattern),通过静态多态技术提高运行效率的同时保持灵活性。 以下是基于上述特性的代码示例展示如何利用空类: ```cpp #include <iostream> using namespace std; // 定义一个简单的空类 class Marker {}; template<typename T> void process(T t) { cout << "Processing generic type." << endl; } // 对于特定类型进行特殊处理 template<> void process(Marker m) { cout << "Special processing for marker class!" << endl; } int main(){ Marker mark; process(mark); // 输出 Special processing for marker class! struct AnotherEmpty {}; process(AnotherEmpty{}); // 调用了通用版本 return 0; } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值