1、结构体/类大小 字节对齐问题(使用 sizeof 验证)
1)简单数据类型:无需对齐
有sizeof(int)=4,sizeof(double)=8。对于数组而言有:
#include<iostream>
using namespace std;
int main()
{
int a[3];
cout<<sizeof(a);
return 0;
}
输出结果为12。所以数组的大小即为数组数×sizeof(datatype)
2)结构体/类中:编译器需要字节对齐
1、成员的偏移量必须是成员长度的整数倍(对于第一个成员,0算任何数的整数倍)
2、结构体的大小是所有成员大小的整数倍(即,是所有成员的公倍数)
class A
{
public:
};
int main()
{
/**
* @brief 16 字节对齐、静态变量不影响类的大小、vptr指针=8
*/
cout << sizeof(A) << endl;
return 0;
对应例1:sizeof长度对应
class A //1
{
public:
char b;
};
class A //4
{
public:
int k;
};
class A//8
{
public:
char b;
int k;
};
class A //16,其中cp1-cp4填充1四字节,cp5填充1四字节
{
public:
char b;
int k;
char cp1;
char cp2;
char cp3;
char cp4;
char cp5;
};
class A//20 ,b、cp2分别占四字节
{
public:
char b;
int k;
char cp2;
int p;
char cp;
char cp3;
char cp4;
};
对应例2:必须是所有成员变量的公倍数
大小:32 ,以1,4,8为单位向前填充
class A//32
{
public:
char b;//8
double k;//16
char cp2;//20
int p;//24
char cp;//25
char cp3;//26
char cp4;//27,填充至32
};
2、结构体/类的大小计算:含空,虚函数,静态变量等问题
1)空类大小:1
class A{};
int main()
{
cout<<sizeof(A)<<endl;
return 0;
}
sizeof输出:1
2)静态变量、成员函数(静态、非静态、虚函数本身)都不占长度
class A {
static int a;
int add(static int a) {
return a + a;
};
};
sizeof输出:1
3)含虚函数时,无论包含多少个,只占一个虚函数指针vcptr的长度(8)
无实际占用量、单虚函数:(1)
class A {
int add() {};
virtual void fun() {};
};
sizeof输出:8
有占用量、单虚函数:
class A {
int b;
int add(static int a) {
return a + a;
};
virtual void fun() {};
};
sizeof输出:16
多个虚函数时:
class A {
int b;
int add(static int a) {
return a + a;
};
virtual void fun() {};
virtual void fun2() {};
};
sizeof输出:16
4)普通继承,派生类继承父类所有成员,要同时依照本类和父类进行对齐;类内使用其他类,也要相应按照成员对齐。
#include<iostream>
using namespace std;
class A
{public:
char a;
int b;
};
class B :public A {
};
class C :A {
public:
short a;
long b;
};
class D {
A a;
char c;
};
int main()
{
cout << sizeof(A) << endl;//8
cout << sizeof(B) << endl;//8
cout << sizeof(C) << endl;//16
cout << sizeof(D) << endl;//12
return 0;
}
sizeof输出:8,8,16,12
5)虚继承、虚函数继承,存疑
#include<iostream>
using namespace std;
class A
{
virtual void fun() {}
};
class B
{
virtual void fun2() {}
};
class C : virtual public A
{
public:
virtual void fun3() {}
};
class C1 : virtual public A
{
};
class D : virtual public A, virtual public B
{
public:
virtual void fun4() {}
};
int main()
{
/**
* @brief 8 8 21 16 32 派生类虚继承多个虚函数,会继承所有虚函数的vptr?
*/
cout << sizeof(A) << " " << sizeof(B) << " " << sizeof(C) << " " << sizeof(C1) << " " << sizeof(D) << endl;
return 0;
}
6)可能存在编译器优化
* @brief 此时B按照顺序:
* char a
* int b
* short a
* long b
* 根据字节对齐4+4+8+8=24
*
* 或编译器优化
* char a
* short a
* int b
* long b
* 根据字节对齐2+2+4+8=16
参考添加链接描述