先看一个空的类占多少空间?
注意到我这里显示声明了构造跟析构,但是sizeof(Base)的结果是1.
因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
而析构函数,跟构造函数这些成员函数,是跟sizeof无关的,也不难理解因为我们的sizeof是针对实例,而普通成员函数,是针对类体的,一个类的成员函数,多个实例也共用相同的函数指针,所以自然不能归为实例的大小,这在我的另一篇博文有提到。
接着看下面一段代码
{
public:
Base();
virtual ~Base(); //每个实例都有虚函数表
void set_num(int num) //普通成员函数,为各实例公有,不归入sizeof统计
{
a=num;
}
private:
int a; //占4字节
char *p; //4字节指针
};
{
public:
Derive():Base(){};
~Derive(){};
private:
static int st; //非实例独占
int d; //占4字节
char *p; //4字节指针
{
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derive)<<endl;
return 0;
}
结果自然是
12
20
Base类里的int a;char *p;占8个字节。
而虚析构函数virtual ~Base();的指针占4子字节。
其他成员函数不归入sizeof统计。
Derive类首先要具有Base类的部分,也就是占12字节。
int d;char *p;占8字节
static int st;不归入sizeof统计
所以一共是20字节。
在考虑在Derive里加一个成员char c;
{
public:
Derive():Base(){};
~Derive(){};
private:
static int st;
int d;
char *p;
char c;
这个时候,结果就变成了
12
24
一个char c;增加了4字节,说明类的大小也遵守类似class字节对齐,的补齐规则。
至此,我们可以归纳以下几个原则:
1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节。
4.类的总大小也遵守类似class字节对齐的,调整规则。
http://blog.csdn.net/hairetz/article/details/4171769
问题引入:经常看到有人说,在C++中如果定义空类/空结构,用sizeof对其取长度结果是1,
疑问:对于这个结果个人比较困惑,无法确定是否正确,所以做了一系列测试来验证说法
测试环境:gcc 3.4.4,vc++6.0,CVI8.0.0
在msdn中对sizeof的使用中有如下一句话
引用:"...The sizeof operator never yields 0, even for an empty class...."
也就是说sizeof不会返回0,那是不是确实是这样的呢?
具体sizeof的使用可以参见msdn!
由于结构体和类的性质基本上相同,而且为了使代码可以在gcc中编译,因此在测试程序中只定义了结构体
约定:为了方便阐述问题,先在叙述前确定几个名词
空结构或者空类:只有关键字的空壳结构或者类
类空结构或者类空类:在空结构或者空类基础上在其内部添加一个成员变量char a[0]; (无任何参考,只是人为约定)
程序保存在test.c中
测试程序如下:
类空结构或者类空类:
#include <stdio.h>
struct A
{
char a[0];
};
int main()
{
printf("%d", sizeof(struct A));
return 0;
}
GCC下:
用gcc编译指令
$ gcc -g -Wall test.c -o test
或者g++编译指令
$ g++ -g -Wall test.c -o test
$ ./test
运行输出:
0 ->这个结果直接推翻了sizeof不返回0的说法,看来是gcc编译器扩展后的一些问题
在VC6.0下
直接编译运行输出:
1 ->与预期一致,因为char a[0],a确实未占用任何空间,此时A相当于是个空类
将上面的程序进行修改一下
空结构或者空类:
#include <stdio.h>
struct A
{
//直接定义一个空类
};
int main()
{
printf("%d", sizeof(struct A));
return 0;
}
GCC下:
用gcc编译运行输出:
0
但是用g++编译运行却输出:
1
在VC6.0下
直接编译运行输出:
1
为了确定gcc的正确性,笔者特地将代码转换成汇编查看了一下,结果确实如前面所述,丝毫不差!
另外,再次说明如果将结构体换成类,其余不变,结果也如上面所说
总结:
1。gcc下空类或者空结构,类空类或者类空结构,其sizeof返回0
2。g++下空类或者空结构其sizeof返回1,对类空类或者类空结构