我想知道一个空类的对象的大小.它肯定不能是0字节,因为它应该可以像任何其他对象一样引用和指向它.但是,这样的对象有多大?
我用过这个小程序:
#includeusing namespace std; class Empty {}; int main() { Empty e; cerr << sizeof(e) << endl; return 0; }
我在Visual C++和Cygwin-g ++编译器上得到的输出是1个字节!这对我来说有点令人惊讶,因为我期望它的机器字大小(32位或4字节).
任何人都可以解释为什么 1字节的大小?为什么不是 4个字节?这是依赖于编译器还是机器?此外,有人可以给出一个更有说服力的理由,说明为什么空类对象的大小不是 0字节?
引用Bjarne Stroustrup的C++样式和技术FAQ,大小非零的原因是"确保两个不同对象的地址不同." 并且大小可以是1,因为在这里对齐并不重要,因为实际上没有什么可以看.
该标准规定所有派生的对象都具有sizeof()> = 1:
除非它是位字段(class.bit),否则大多数派生对象应具有非零大小并且应占用一个或多个存储字节.基类子对象可以具有零大小. ISO/IEC FDIS 14882:1998(E)intro.object
这真的是一个实现细节.很久以前,我认为它可能是零字节或一千字节,它与语言规范无关.但是,在查看标准(第5.3.3节)之后,sizeof
定义为总是返回一个或更大,无论如何.
最派生类的大小应大于零.
除其他外,这是允许您处理对象数组和指向它们的指针所必需的.如果你的元素被允许为零大小,那么它们&(array[0])
将是相同的&(array[42])
,这将对你的处理循环造成各种各样的破坏.
它可能不是机器字的原因是它内部没有实际要求它在字边界上对齐的元素(例如整数).例如,如果放在char x; int y;
类中,我的GCC将其计时为8个字节(因为第二个int必须在该实现中对齐).
有一个例外:0长度数组
#includeclass CompletlyEmpty { char NO_DATA[0]; }; int main(int argc, const char** argv) { std::cout << sizeof(CompletlyEmpty) << '\n'; }
即使它不需要为空类分配任何内存,但为了使空类的对象,编译器分配可分配的最小内存,即1个字节.这样,编译器可以唯一地区分同一空类的两个对象,并且能够将对象的地址分配给空类类型的指针.