【发布时间】:2011-01-25 04:14:39
【问题描述】:
C++ 和 Java 中空类的大小是多少?
为什么不是零?
sizeof(); 在 C++ 的情况下返回 1。
【问题讨论】:
标签: java c++ empty-class
C++ 和 Java 中空类的大小是多少?
为什么不是零?
sizeof(); 在 C++ 的情况下返回 1。
【问题讨论】:
标签: java c++ empty-class
C++ 标准明确规定类的大小不能为零。
因为每个对象都需要有一个唯一的地址(也在标准中定义),所以您不能真正拥有零大小的对象。
想象一个零大小的对象数组。因为它们的大小为零,所以它们都将排列在相同的地址位置。所以说对象的大小不能为零更容易。
即使对象的大小不为零,但如果它实际上占用了零空间,则不需要增加派生类的大小:
例子:
#include <iostream>
class A {};
class B {};
class C: public A, B {};
int main()
{
std::cout << sizeof(A) << "\n";
std::cout << sizeof(B) << "\n";
std::cout << sizeof(C) << "\n"; // Result is not 3 as intuitively expected.
}
g++ ty.cpp
./a.out
1
1
1
【讨论】:
在 Java 案例中:
sizeof 运算符。Instrumentation 或 3rd 方库)会给您一个数字,但含义很微妙1;见In Java, what is the best way to determine the size of an object? “空类”(即java.lang.Object)的实例的大小不为零,因为该实例具有与之关联的隐式状态。例如,需要状态:
当前的 Hotspot JVM 使用巧妙的技巧来表示占用两个 32 位字的对象标头中的状态。 (这在某些情况下会扩展;例如,当实际使用原始锁时,或在调用 identityHashCode() 之后。)
1 - 例如,new String("hello") 创建的字符串对象的大小是否包括保存字符的后备数组的大小?从 JVM 的角度来看,该数组是一个单独的对象!
【讨论】:
因为每个 C++ 对象都需要有一个单独的地址,所以不可能有一个大小为零的类(除了一些与基类相关的特殊情况)。 C++: What is the size of an object of an empty class? 有更多信息。
【讨论】:
因为一个对象必须在内存中有一个地址,而在内存中有一个地址,它必须占用“一些”内存。因此,在 C++ 中,它通常是可能的最小数量,即 1 个字符(但这可能取决于编译器)。在 Java 中,我不太确定.. 它可能有一些默认数据(不仅仅是 C++ 中的占位符),但如果它比 C++ 中的多得多,那就令人惊讶了。
【讨论】:
C++ 要求其正常实例化的大小至少为 1(可能更大,尽管我不知道有哪个编译器可以做到这一点)。然而,它允许“空基类优化”,因此即使该类的最小大小为 1,但当它用作基类时,它确实不必添加任何大小到派生类。
我猜Java 可能做的差不多。 C++ 要求大小至少为 1 的原因是它要求每个对象都是唯一的。例如,考虑一个大小为零的对象数组。所有的对象都在同一个地址,所以你真的只有一个对象。让它为零听起来像是问题的根源......
【讨论】:
它被 C++ 标准定义为“非零值”,因为分配的对象必须具有非零大小才能具有不同的地址。但是,从空类继承的类不需要增加大小,除非涉及到虚函数,通常会增加 vtable。
【讨论】:
不知道java中是否有sizeof()操作符。您可以做的是创建一个空类的实例(使其可序列化),通过 PipedOutputStream 发送它并将其作为字节数组读取 - byteArray.length 为您提供大小。
或者,使用 DataOutputStream 将实例写入文件,关闭文件,打开它,file.length() 将为您提供对象的大小。希望这会有所帮助,-M.S.
【讨论】:
正如其他人所指出的,C++ 对象的大小不能为零。只有当它们充当不同类的子类时,类才能具有零大小。查看@Martin York 的answer 以获取示例描述——同时查看并投票选出在这方面正确的其他答案。
在 Java 中,在hotspot VM 中,每个对象有 2 个机器字(通常每个字 32 个拱形中的 4 个字节)的内存开销来保存簿记信息和运行时类型信息。对于数组,需要第三个字来保存大小。其他实现可以占用不同的内存量(经典的 Java VM,根据相同的引用,每个对象占用 3 个单词)
【讨论】: