1.103、类对象的大小受哪些因素影响?

类对象的大小受多种因素影响,主要包括成员变量、内存对齐、虚函数机制、继承方式等,具体如下:


1. 普通非静态成员变量的大小

  • • 类对象的大小至少是其所有非静态数据成员大小的总和(考虑内存对齐)。
  • • 静态成员变量不占对象空间,因为静态成员属于类本身,存储在静态存储区。
  • • 成员函数(无论普通还是静态)不影响对象大小。

2. 内存对齐(Padding)

  • • 编译器为了提高访问效率,会按最大成员类型的对齐要求对类对象进行字节对齐。
  • • 对象大小会被填充到对齐边界的整数倍,可能导致实际大小大于成员大小之和。
  • • 对齐规则通常为类中最大成员类型的大小(但不会超过编译器或平台规定的最大对齐数,如8字节)。
  • • 成员的排列顺序会影响内存填充和最终大小,合理排序可减少内存浪费。

3. 虚函数引入的额外开销

  • • 如果类含有虚函数,编译器会为对象添加一个虚函数表指针(vptr),占用一个指针大小(32位系统4字节,64位系统8字节)。
  • • 虚函数表指针是对象内存的一部分,导致类对象大小增加。
  • • 虚继承还会引入虚基表指针,进一步增加对象大小。

4. 继承影响

  • • 单继承:派生类对象大小 = 基类对象大小 + 派生类新增成员大小(均考虑对齐)。
  • • 多继承:所有基类成员大小累加,可能有额外的对齐填充。
  • • 虚继承:为解决菱形继承问题,虚基类子对象通过指针间接访问,增加虚基表指针,导致对象大小增加。
  • • 空基类优化(EBO):空类作为基类时通常不增加派生类对象大小。

5. 空类大小

  • • 空类(无成员变量、无虚函数)大小为1字节,保证每个对象有唯一地址。
  • • 空类作为基类时,编译器通常会进行空基类优化,不增加派生类大小。

总结表格

影响因素 说明
非静态成员变量 直接影响对象大小,按类型大小累加
静态成员变量 不占对象空间,存储在静态区
内存对齐 按最大成员类型对齐,可能填充字节
虚函数 增加虚函数表指针,增加对象大小
继承 基类成员大小累加,虚继承增加虚基表指针
空类 大小为1字节,空基类优化不增加派生类大小
成员函数 不影响对象大小

典型示例

class A {
    int a;      // 4字节
    char b;     // 1字节
    // 3字节填充,保证4字节对齐
};

class B : public A {
    virtual void foo() {}  // 添加虚表指针,增加4或8字节
    double d;              // 8字节
};

sizeof(A)可能为8(4+1+3填充),sizeof(B)至少为16或24(基类8 + 虚表指针8 + double 8,具体依平台和编译器而定)。
本文首发于【讳疾忌医-note】公众号,未经授权,不得转载。
(加入我的知识星球,免费获取账号,解锁所有文章。)

阅读剩余
THE END