1. 计算类对象的大小
类实例化的对象中只存储成员变量,不存储成员函数,函数要用是通过 this 指针拿的。因为一个类可以实例化出 N 个对象,每个对象的成员变量都可以存储不同的值,但是调用的函数却是同一个。如果每个对象都成员函数,每个成员函数都是同样的,就会浪费空间。
如果我们需要计算一个类实例化出的对象的大小,那就只用考虑成员变量占用内存之和(和结构体占用内存大小一样,需要考虑内存对齐规则)
// 类中既有成员变量,又有成员函数
class A1 {
public:void f1() {}
private:int _a;
};// 类中仅有成员函数
class A2 {
public:void f2() {}
};// 类中什么都没有---空类
class A3
{};int main()
{A1 a1;A2 a2;A3 a3;// 打印每个类实例化后的对象的大小// 没有成员变量的类的大小是 1cout << sizeof(a1) << endl; // 4字节cout << sizeof(a2) << endl; // 1字节cout << sizeof(a3) << endl; // 1字节return 0;
}
为什么没有成员变量的类的对象的大小是 1 字节,而不是 0 字节?
此时开一个字节不是为了存数据,而是占位,表示对象存在。不然,遇到下面这种情况:
// 类中什么都没有---空类
class A3
{};int main()
{A3 a1;A3 b1;A3 c1;
}
如果没有成员变量的类的大小是 0 字节,此时如果对 a1,b1,c1 取地址,那该得到什么样的地址呢?所以需要一个字节占位。
2. 结构体内存对齐规则
1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的对齐数为8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。