注册 登录
编程论坛 C++教室

[开源]有关static member 的 小测试 程序

cpluslover 发布于 2007-04-29 18:20, 1391 次点击

code 如下:

#include<iostream>
using namespace std;

class X
{
int a;
static int b;
};

int X::b=0;

class Y
{
int a;
};

class Z
{
static int b;
};

int Z::b=0;

class WQ
{
};

int main()
{
cout<<"静态成员测试如下:"
<<"X size is: "<<sizeof(X)<<endl
<<"Y size is: "<<sizeof(Y)<<endl
<<"Wq size is: "<<sizeof(WQ)<<endl
<<"Z size is: "<<sizeof(Z)<<endl;
return 0;
}

由此可看出一个类不是空的,它占1个字节
静态成员 不在类中占分配空间, 普通成员在类中占有分配空间

16 回复
#2
aipb20072007-04-29 21:40


空的类也占一个字节!
#3
I喜欢c2007-04-29 22:47
class X
{ static int b;
int a;
char c;
};

这样呢?
#4
weishj2007-04-30 16:04

首先说明以下是我的猜想,具体还请高手指点,说错了大家也别骂我呵
类在实例化之前不占内存吧
另外sizeof操作符从来不返回0,所以空类对象是否占一个字节还不能用sizeof来确定
The sizeof operator never yields 0, even for an empty class.(本句摘自MSDN)
还有就是如果一个空类真的占一个字节的话,那么
class X
{
int a;
static int b;
};
是不是应该占八个字节了但用sizeof试一下发现结果是4
class X
{ static int b;
int a;
char c;
};
这个用sizeof求了一下结果是8,也说明空类不占内存的呀

#5
cpluslover2007-04-30 16:12
class X
{
int a;
static int b;
};
是不是应该占八个字节了但用sizeof试一下发现结果是4

这是不对的,应该知道,static变量 不是属于类的,所以它不在类中占内存,所以只能说是int占的字节 即4个字节

另外一个空类的大小不为0这是肯定的,如果是0的话你建立两个空对象的话怎么区分它们呢
这就是空类大小不为空的一个重要原因。
然后你说的这个用sizeof求了一下结果是8,也说明空类不占内存的呀
这个涉及到空基类的优化问题,具体请看这里https://bbs.bc-cn.net/viewthread.php?tid=76914
#6
cpluslover2007-04-30 16:15
以下是引用I喜欢c在2007-4-29 22:47:22的发言:
class X
{ static int b;
int a;
char c;
};

这样呢?

应该是5个吧

static 不在类中占内存,它在内存上不属于类,所以应该占5个,空基类优化了,空的那1个字节不计算在内。
我想是这样的

#7
weishj2007-04-30 16:27
static数据在类中不占内存我知道
class X
{ static int b;
int a;
char c;
};
其对象占八个字节内存,这是毫无疑问的,int 占四个字节,char 一个字节,但要考虑字节对齐,所以要有三个字节的填充位

[此贴子已经被作者于2007-4-30 16:30:58编辑过]

#8
cpluslover2007-04-30 16:39


谢谢楼上的指正,又长知识了,说的很对,要对齐才行。
#9
weishj2007-04-30 16:47

也非常感谢楼主给我提供一个这么好的帖子,正在学习中
https://bbs.bc-cn.net/viewthread.php?tid=76914

#10
I喜欢c2007-04-30 17:01

恩~```
不错.....
大家说的很有道理

都学的不错嘛..LZ这种精神很值得大家学习呀~``

#11
aipb20072007-04-30 20:24
确实不错啊,我都没去想这么多,长见识了!
#12
yuyunliuhen2007-05-01 01:22
以下是引用weishj在2007-4-30 16:27:56的发言:
static数据在类中不占内存我知道
class X
{ static int b;
int a;
char c;
};
其对象占八个字节内存,这是毫无疑问的,int 占四个字节,char 一个字节,但要考虑字节对齐,所以要有三个字节的填充位


就是要这样讨论,我们才会有更多的收获,俺也学习了

#13
yuyunliuhen2007-05-01 01:46

我们先排掉static 的干扰,我们可以让它显示出真实的值

class A //64bit,x86环境,VC编译器

{
int a;
char b;
short c;
};
class B
{
char b;
int a;
short c;
};
现在已知64位机器上各种数据类型的长度如下:
char:1(有符号无符号同)
short:2(有符号无符号同)
int:4(有符号无符号同)
long:4(有符号无符号同)
float:4 double:8
那么上面两个结构大小如何呢?
结果是:
sizeof(class A)值为8
sizeof(class B)的值却是12

结构体A中包含了4字节长度的int一个,1字节长度的char一个和2字节长度的short型数据一个,B也一样;按理说A,B大小应该都是7字节。
之所以出现上面的结果是因为编译器要对数据成员在空间上进行对齐。上面是按照编译器的默认设置进行对齐的结果,那么我们是不是可以改变编译器的这种默认对齐设置呢,当然可以.例如:
#pragma pack (2) /*指定按2字节对齐*/
class C
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
sizeof(class C)值是8。
修改对齐值为1:
#pragma pack (1) /*指定按1字节对齐*/
class D
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
sizeof(class D)值为7。

#14
dengrenfu2007-05-01 09:30
#15
nuciewth2007-05-01 09:45

计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。


sizeof使用场合。
1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:    void *malloc(size_t size), 
  size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。

2.用它可以看看一类型的对象在内存中所占的单元字节。 void * memset(void * s,int c,sizeof(s))

3.在动态分配一对象时,可以让系统知道要分配多少内存
4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。
5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
6.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

#16
cpluslover2007-05-01 12:05
以下是引用yuyunliuhen在2007-5-1 1:46:54的发言:

我们先排掉static 的干扰,我们可以让它显示出真实的值

class A //64bit,x86环境,VC编译器

{
int a;
char b;
short c;
};
class B
{
char b;
int a;
short c;
};
现在已知64位机器上各种数据类型的长度如下:
char:1(有符号无符号同)
short:2(有符号无符号同)
int:4(有符号无符号同)
long:4(有符号无符号同)
float:4 double:8
那么上面两个结构大小如何呢?
结果是:
sizeof(class A)值为8
sizeof(class B)的值却是12

结构体A中包含了4字节长度的int一个,1字节长度的char一个和2字节长度的short型数据一个,B也一样;按理说A,B大小应该都是7字节。
之所以出现上面的结果是因为编译器要对数据成员在空间上进行对齐。上面是按照编译器的默认设置进行对齐的结果,那么我们是不是可以改变编译器的这种默认对齐设置呢,当然可以.例如:
#pragma pack (2) /*指定按2字节对齐*/
class C
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
sizeof(class C)值是8。
修改对齐值为1:
#pragma pack (1) /*指定按1字节对齐*/
class D
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
sizeof(class D)值为7。


版主研究的可真深入啊

又学习了
强人啊

#17
cpluslover2007-05-01 12:09
以下是引用nuciewth在2007-5-1 9:45:50的发言:

计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。


sizeof使用场合。

5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。

5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。

再次学习了

1