空类大小为1字节,因C++标准要求对象有唯一地址,编译器隐式插入char确保sizeof至少为1;验证应直接用sizeof,不可依赖地址差值。

空类的大小为什么不是0字节
因为C++标准要求每个对象必须有唯一地址,如果空类大小为0,那么同一作用域中多个空类对象就可能被分配到相同地址,违反对象身份原则。编译器会隐式插入一个char成员(或等效填充),确保sizeof至少为1。
如何验证空类实际大小
直接用sizeof操作符测试最可靠。注意:不能依赖打印地址差值来推断,因为栈上局部变量的布局受对齐和编译器优化影响,不一定连续。
struct Empty {};
int main() {
std::cout << sizeof(Empty) << "\n"; // 通常输出 1
std::cout << sizeof(Empty{}) << "\n"; // 同样是 1
}
继承空基类时的字节占用变化
当空类作为基类时,多数现代编译器(GCC、Clang、MSVC)会启用“空基类优化”(EBCO),不为其单独分配空间——前提是它不与派生类的其他成员地址重叠。
-
struct Base {};→sizeof(Base) == 1 -
struct Derived : Base { int x; };→sizeof(Derived)通常仍为4(x自身占4字节,Base不额外占空间) - 但若
Derived含char成员且未对齐,EBCO仍可能生效,具体取决于成员顺序和目标平台对齐规则
含有虚函数的空类大小会变大
一旦加入虚函数,空类会隐含一个虚表指针(vptr),大小由指针宽度决定:在64位系统上通常是8字节,在32位系统上是4字节。
立即学习“C++免费学习笔记(深入)”;
struct EmptyVirtual {
virtual ~EmptyVirtual() = default;
};
// sizeof(EmptyVirtual) 通常是 8(x86_64)或 4(x86)
这个vptr是真实存储的成员,不可省略,也不参与EBCO——即使继承该空虚基类,派生类仍需自己的vptr(除非完全不引入新虚函数且复用基类vtable,但实现细节复杂,不应依赖)。
真正容易被忽略的是:空类大小不是“固定1字节”,而是“至少1字节”,且在多重继承、虚继承、对齐要求叠加时,可能因填充而大于1;但单个空类、无虚函数、无对齐干预时,sizeof结果稳定为1。










