为什么类的大小取决于成员声明的顺序?以及如何
Why does the size of a class depends on the order of the member declaration? and How?
有人向我解释了类内成员声明的顺序如何决定该类的大小。
例如:
class temp
{
public:
int i;
short s;
char c;
};
上述类的大小为8字节。
但当成员声明的顺序更改为以下时
class temp
{
public:
char c;
int i;
short s;
};
则类的大小是12个字节。
如何?
上述行为背后的原因是数据结构对齐和填充。基本上,如果您正在创建一个4字节的变量,例如int,它将与四字节边界对齐,即它将从内存中的一个地址开始,该地址是4的倍数。这同样适用于其他数据类型。2字节短应该从偶数内存地址开始,依此类推
因此,如果在int之前声明了一个1字节的字符(此处假定为4字节(,那么在这两个字符之间将剩下3个空闲字节。对它们常用的术语是"填充"。
数据结构对齐
另一个很好的图片解释
对齐原因
填充允许更快的内存访问,即对于cpu来说,访问对齐的内存区域更快。例如,读取一个4字节对齐的整数可能需要一次读取调用,其中,如果一个整数位于未对齐的地址范围(例如地址0x0002-0x0006(,则需要两次内存读取才能获得该整数。
强制编译器避免对齐的一种方法是(特定于gcc/g++(在structure属性中使用关键字">packed"。packed关键字该链接还指定如何使用aligned关键字通过您选择的特定边界(2、4、8等(强制对齐。
最佳实践
以变量已经与最小填充对齐的方式来构造类/结构总是一个好主意。这减少了类的整体大小,还减少了编译器所做的工作量,即没有重新排列结构。此外,应该始终通过成员变量在代码中的名称来访问它们,而不是试图从结构中读取特定的字节,假设值位于该字节。
关于对准性能优势的另一个有用SO问题
为了完成,在您的场景(32位机器(中,下面的仍然有8个字节的大小,但它不会变得更好,因为完整的8个字节现在被占用了,并且没有填充。
class temp
{
public:
int i;
short s;
char c;
char c2;
};
class temp
{
public:
int i; //size 4 alignment 4
short s; //size 2 alignment 2
char c; //size 1 alignment 1
}; //Size 8 alignment max(4,2,1)=4
temp[i[0-4]s[4-2]c[6-7]]->8填充(7-8(
class temp
{
public:
char c; //size 1 alignment 1
int i; //size 4 alignment 4
short s; //size 2 alignment 2
};//Size 12 alignment max(4,2,1)=4
temp[c[0-1]i[4-8]s[8-10]]->12填充(1-4(和(10-12(
- 在循环中按顺序遍历成员变量
- C++成员的析构函数顺序与shared_ptr
- 按类成员的顺序对包含类对象的C++向量进行排序
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 用作成员构造函数参数的函数的求值顺序
- 成员初始值设定项的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 共享库中静态功能成员的破坏顺序
- C++11 成员类初始化顺序
- 静态内联成员初始化顺序
- 更改 std::set 作为成员属性的顺序
- 位成员顺序相反?
- C++中的类私有成员的内存顺序是否得到保证?
- 静态成员的静态阵列:初始化顺序惨败的可能性
- C++-销毁顺序-函数的静态成员在主类析构函数之前被销毁
- 为什么在定义静态成员变量时不遵循定义顺序
- 如何维护类成员的顺序,并且仍然有一个可工作的构造函数
- 编译时随机化结构成员的顺序
- 类模板中成员变量的顺序