对class求sizeof的问题总结
首先看如下代码:
1 class A 2 { 3 public: 4 A(){}; 5 ~A(){}; 6 private: 7 int a; 8 double b; 9 }; 10 11 class B:public A 12 { 13 public: 14 B(){}; 15 ~B(){}; 16 private: 17 int a; 18 char b; 19 }; 20 21 cout <<sizeof(A)<<sizeof(B)<<endl;
首先,class的sizeof遵循以下几点:
1、class大小为非静态成员类型之和,也就是说静态成员数据,如static不作为sizeof的统计范围。
如以下代码运行结果是:1。
1 struct A 2 { 3 char c; 4 static int a; 5 }; 6 cout << sizeof(A)<<endl;
2、普通成员函数不作为sizeof统计范围,包括构造析构函数。
如以下代码运行结果是:4。
1 class A 2 { 3 public: 4 show(); 5 private: 6 int a; 7 }; 8 cout <<sizeof(A)<<endl;
3、虚函数要维护虚函数表,占用一个指针,四个字节。
如以下代码运行结果是:4。
1 class A 2 { 3 public: 4 virtual A(){}; 5 }; 6 cout<<sizeof(A)<<endl;
4、class遵守字节对齐规则。
其中,字节对齐的讲解如下:
1、第一个数据成员的offset=0地方,其后每个成员从该成员的大小或者成员的倍数出开始存储。
如在32位系统中
char为1字节,可在任意位置存储;
int为4字节,只能在0-3 4-7 8-11 12-15...这些位置开始存放;
double为8字节,只能在0-7 8-15...这些位置开始存放;
为什么要这样做:因为可以提高计算机读取数据的速度,只从数据的倍数索引出进行查找,不必逐个或者跳跃查找。
2、含有数据成员为结构体或者其他类时,从其最大的子成员的倍数处开始存储。
1 struct A 2 { 3 double a; 4 }; 5 6 struct B 7 { 8 int a; 9 A b; 10 }; 11 cout << sizeof(B)<<endl;
如以上代码中,A的sizeof为8字节,首先B中的int a为[0,3]存放,然后存放A b为8字节,Ab中最大子成员为double 8字节,因此必须从[8-15]开始存放,所以答案为16。
3、最终长度为其最大成员长度的倍数。
1 struct A 2 { 3 int a; 4 char c; 5 }; 6 cout << sizeof(A) <<endl;
答案是:8。A的最大成员长度为4,int a[0-3],char c[4],[5-7]补全。
且听我一步步来解释:
行号1: 声明class A,若A时空类,此时sizeof(A)是1,不是0,解释可以查看我的上一篇文章《C++空类的sizeof》。
行号2-5:声明的成员函数,不纳入sizeof统计范围。
行号7-8:成员变量int为4字节,double为8字节,则总共为12字节?不对,根据字节对齐,下面再讲,class A的总大小为16字节。
同理,class B中继承了class A,则首先有16字节了,成员变量int a和char b,字节数分别为4和1,根据字节对齐总大小为24字节。
总结得较为杂乱,欢迎讨论。