C ++和Java中空类的大小是多少?
为什么不是零?
对于C ++,sizeof();
返回1。
答案 0 :(得分:26)
标准明确指出一个类的大小不能为零。
因为每个对象都需要一个唯一的地址(也在标准中定义),所以你不能真正拥有零大小的对象 想象一下零大小的对象数组。因为它们的大小为零,所以它们都排在同一个地址位置。因此,更容易说对象的大小不能为零。
注意:即使对象的大小为非零,如果它实际占用零空间,也不需要增加派生类的大小:
示例:
#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
答案 1 :(得分:14)
在Java案例中:
sizeof
运营商。Instrumentation
或第三方库)会给你一个数字,但意思是细微差别 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的角度来看,该数组是一个单独的对象!
答案 2 :(得分:4)
因为每个C ++对象都需要一个单独的地址,所以不可能有一个零大小的类(除了一些与基类相关的特殊情况)。 C++: What is the size of an object of an empty class?中有更多信息。
答案 3 :(得分:4)
因为一个对象必须在内存中有一个地址,并且在内存中有一个地址,所以它必须占用“一些”内存。因此,在C ++中,它通常是可能的最小量,即1个字符(但可能取决于编译器)。在Java中,我不太确定......它可能有一些默认数据(不仅仅是像C ++中的占位符一样),但如果它比C ++中的更多,那就太令人惊讶了。
答案 4 :(得分:3)
C ++要求它的正常实例化大小至少为1(可能更大,但我不知道编译器会这样做)。但它允许“空基类优化”,所以即使该类的最小大小为1,当它用作基类时,不必须添加任何大小的类派生类。
我猜测 Java可能几乎一样。 C ++需要大小至少为1的原因是它要求每个对象都是唯一的。例如,考虑一个大小为零的对象数组。所有对象都在同一个地址,所以你真的只有一个对象。允许它为零听起来像是一个问题的秘诀......
答案 5 :(得分:2)
它被C ++标准定义为“非零值”,因为分配的对象必须具有非零大小才能具有不同的地址。但是,从空类继承的类不需要增加大小,除非涉及虚函数,否则通常会增加vtable。
答案 6 :(得分:0)
我不知道java中是否有sizeof()运算符。你可以做的是创建一个空类的实例(让它可序列化),通过PipedOutputStream发送它并将其作为字节数组读取 - byteArray.length为你提供大小。
或者,使用DataOutputStream将实例写出到文件,关闭File,打开它,file.length()将为您提供Object的大小。希望这会有所帮助, - M.S。
答案 7 :(得分:0)
正如其他人所指出的,C ++对象的大小不能为零。只有当类充当不同类的子类时,它们才能具有零大小。请查看@Martin York的answer以获取有关示例的说明 - 并查看并投票选出其他正确的答案。
在Java中,在hotspot VM中,每个对象有2个机器字(通常每个字32个字节中有4个字节)的内存开销,用于保存簿记信息以及运行时类型信息。对于数组,需要第三个字来保持大小。其他实现可以占用不同的内存量(经典Java VM,根据相同的引用,每个对象需要3个字)