• C++ 类的大小 原理+详细计算示例


    大小的组成

    类的大小受:基类,成员,虚基表指针,虚函数表指针 影响。

    计算方式

    需要按照下列要素对齐和规则计算对齐:

    对齐要素

    编译器默认对齐数:根据环境改变,一般32位为4,64位为8。

    有效对齐数:编译器默认对齐数 与 该成员所占字节数的较小值。

    最大对齐数: 最大成员大小 与 编译器默认对齐数取较小值。

    对齐规则

    1.每个元素的起始偏移量是该元素当前有效对齐数的整数倍。

    2.类的大小是最大对齐数的整数倍。

    每种情况下的计算示例

    统一环境为32位机器。

    不考虑继承多态

    最简单不要对齐的例子

    1. class A
    2. {
    3. int a;
    4. };

    int a 起始偏移量为0,是有效对齐数4(min(4,8))的0倍。

    变量a占偏移量为0,1,2,3的字节,共大小的4字节为最小有效对齐数(4)的整数倍。

    需要对齐的例子

    对齐偏移量
    1. class A
    2. {
    3. bool a;
    4. int b;
    5. };

    bool a的起始偏移量为0,占用偏移量为0的字节。

    int b的起始偏移量为1,不是当前有效对齐数(min(4,8))的整数倍

    偏移量为1,2,3的字节空出,int b从占用偏移量为4,5,6,7的字节。

    最终大小为8,为对齐数4的整数倍。

    对齐总大小
    1. class A
    2. {
    3. int* a;
    4. bool b;
    5. };

    int* a占用偏移量为0,1,2,3的字节。

    bool b占用偏移量为4的字节。

    总大小为5,当前最大对齐数为int*大小与默认对齐数的较小值4,而5不是4的整数倍,故对齐后大小为8。

    考虑继承多态

    虚函数表与虚基表亦为类的成员(隐藏成员)故需要考虑对齐,聚焦于类的大小,本文就不再阐述继承多态的实现了。

    非虚继承

    1. class A
    2. {
    3. virtual void func() { ; }
    4. int* a;
    5. bool b;
    6. };//size:8
    7. class B : public A
    8. {
    9. virtual void func()override { ; }
    10. int c;
    11. };

    因为不是虚拟继承,B中只继承A的成员。

    a占偏移量0~3,b占4,c占8~11。

    因为重写了func,故隐藏的虚函数表指针占12~15。

    总大小为16刚好为最大对齐数(最大成员大小为4,默认对齐数为4,取最小还是4)的整数倍。

    虚继承

    1. class A
    2. {
    3. virtual void func() { ; }
    4. int* a;
    5. bool b;
    6. };//size:8
    7. class B : virtual public A //虚继承
    8. {
    9. virtual void func()override { ; }
    10. int c;
    11. };

    虚拟继承实现方式为虚基表指针指向虚基类在类中的偏移量,不清楚的可以先移步,笔者的这篇文章中有详细阐述。

    彻底理解虚拟继承icon-default.png?t=N7T8http://t.csdnimg.cn/4SpKBc占偏移量0~3的字节。

    虚函数表指针占4~7的字节。

    虚基表指针占8~11的字节。

    虚基类A占12~19的字节(当前最大对齐数为min(8,4)12为4的倍数)。

    最大对齐数为min(4,8)=4。

    20为最大对齐数的整数倍,最终大小为20。

  • 相关阅读:
    Debian | Vscode 安装与配置 C 环境
    最常见的35个Python面试题
    websocket实现实时变化图表内容
    ES6 Proxy
    基于springboot的计算机类考研交流平台(源码+论文)
    java计算机毕业设计基于安卓Android的升降式停车场管理系统APP
    软件测试---边界值分析(功能测试)
    未来已来:智慧餐饮点餐系统引领餐饮业的数字化转型
    三电系统集成技术杂谈
    docker容器里面的java进程内存泄露排查
  • 原文地址:https://blog.csdn.net/weixin_44212838/article/details/136432626