c++;具有函数的类的sizeof() 我有一个C++问题。 我写了以下课程: class c { int f(int x, int y){ return x; } };

c++;具有函数的类的sizeof() 我有一个C++问题。 我写了以下课程: class c { int f(int x, int y){ return x; } };,c++,compiler-construction,sizeof,C++,Compiler Construction,Sizeof,类c的sizeof()返回“1”。 我真的不明白为什么它返回1 为了更好地理解正在发生的事情,我添加了另一个函数: class c { int f(int x, int y){ return x; } int g(int x, int y){ return x; } }; 现在下面的内容真的把我弄糊涂了!sizeof(c)仍然是1(!?!?!)。 所以我猜函数不会改变类的大小,但是为什么???为什么尺寸是1?它是特定于编译器的吗 谢谢!:-) 该类不包含数据成员,因此为空。

类c的sizeof()返回“1”。 我真的不明白为什么它返回1

为了更好地理解正在发生的事情,我添加了另一个函数:

class c
{
     int f(int x, int y){ return x; }
     int g(int x, int y){ return x; }
};
现在下面的内容真的把我弄糊涂了!sizeof(c)仍然是1(!?!?!)。 所以我猜函数不会改变类的大小,但是为什么???为什么尺寸是1?它是特定于编译器的吗


谢谢!:-)

该类不包含数据成员,因此为空。标准要求每个班级至少有1号,这就是你得到的。(成员函数在物理上不是“在”类中,它们实际上只是具有隐藏参数、命名空间和访问控制的自由函数。)

它的大小为1,因为它不能为0,否则这种类型的两个对象将无法寻址(无法区分其地址)

1表示1字节。原因是方法不存储在对象中。它们由对象使用,但不存储在对象中。只有类成员存储在对象中。尝试添加一个普通的
int
成员或其他什么,看看会发生什么。

成员函数本质上与常规函数相同,它们只是得到一个隐藏的
参数。因此,给定类型的每个实例不需要携带其成员函数的副本;编译器只是跟踪常规函数,并为您提供适当的
this
参数。因此,无论给定类型有多少个函数,其大小都不需要更改。当您使用虚拟函数等进行复杂的继承时,这种情况会略有改变,但最终函数的数量仍然不会影响对象的最终大小

一个字节的初始大小是因为所有对象都必须占用一些空间,因此可以保证没有两个对象占用相同的空间。考虑数组…code>a[5]与
*(a+5)
相同,添加到指针会根据对象的大小增加内存地址。如果
sizeof(a)
0
,则数组的所有元素都将塌陷到同一地址

某些空间的对象类型是由标准规定的。。。大小正好等于1是不正确的
sizeof(c)
在您的情况下可能是23,但没有理由这样做

为了完整性,子对象的大小可能为零。空基优化允许基类不占用任何实际内存(如果不需要)。因此,
sizeof(Base)==sizeof(Derived)
可能是真的,即使形式上
Derived
包含一个隐藏在其中的
Base
实例。这是标准允许的,但不是强制性的。。。例如,MSVC在某些情况下不使用它

因为您的类是一个“引用变量”,并且根据MSDN:“sizeof运算符即使对于空类也不会产生0。”

例如:

#包括

c类 { 公众: intf(intx,inty){返回x;} int g(int x,int y){return x;} };

结构 { int f; int g; };

int main(int argc,char*argv[]) { c objc; s objs; printf(“sizeof(c)=%d,sizeof(objc)=%d,sizeof(c类)=%d…”, sizeof(c)、sizeof(objc)、sizeof(c类)); printf(“sizeof(s)=%d,sizeof(objs)=%d,sizeof(struct s)=%d…”, sizeof(s)、sizeof(objs)、sizeof(struct s)); 返回0; }

结果:

sizeof (c)= 1, sizeof (objc)= 1, sizeof (class c)= 1... sizeof (s)= 8, sizeof (objs)= 8, sizeof (struct s)= 8... sizeof(c)=1,sizeof(objc)=1,sizeof(c类)=1。。。 sizeof(s)=8,sizeof(objs)=8,sizeof(struct s)=8。。。 还要注意“struct”和“class”之间的区别

以下是更多信息:

问:虚拟函数是否会占用每个对象的空间,从而增加对象的大小

答:不是。虚拟功能越多,vtable越大。子类越多,vtables就越多。如果类没有虚函数,则不需要vtable或(每个对象)vtable指针

但这些都不会影响“sizeof”。不管怎样,函数本身占用固定的空间

sizeof(char)==1,因为char是一个字节,sizeof返回一个数字 字节数。(但是,一个字节不一定正好是八位。)

绝对正确。因此出现了术语“八位字节”(将8位与更常用的术语“字节”区分开来)

有关更多信息,请参阅IEEE 1541:


从技术上讲,标准规定所有东西都必须有地址。(如果大小不能为零,则空基优化将不起作用)@Tobias:通常不会。添加虚拟函数将使对象的大小增加指针大小,指针指向该类型使用的所有虚拟函数的列表。额外的虚拟函数会增加该列表的大小,但您仍然只需要在每个对象的基础上携带一个指针。当然,这些都不是标准强制要求的。@Chris:
sizeof
永远不能返回0。机器上最小的可寻址单元被定义为
char
,它被定义为
1
。任何东西都要有地址,它必须是可寻址的。“所有内容都必须有一个地址”和“所有内容都必须有非零大小”之间的唯一区别是空基优化,这不会影响
sizeof
@Chris的使用:标准规定所有内容都必须是可寻址的。编译器可以进行优化,使基类和派生类具有相同的地址
sizeof
将始终至少返回1,即使基类实际上没有大小(它与派生类实例共享地址)。请参阅:请这样想:对象的大小是通过将其存储需求(包括对象的存储需求)相加来计算的 sizeof (c)= 1, sizeof (objc)= 1, sizeof (class c)= 1... sizeof (s)= 8, sizeof (objs)= 8, sizeof (struct s)= 8...