zoukankan      html  css  js  c++  java
  • C++一个类对象的大小计算

      计算一个类对象的大小时的规律:   

     1、空类、单一继承的空类、多重继承的空类所占空间大小为:1(字节,下同);

        2、一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的;

        3、因此一个对象的大小≥所有非静态成员大小的总和(包括动态分配的变量...);

        4、当类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针vPtr指向虚函数表VTable;

        5、虚继承的情况:虚继承的实现是通过一个虚基类指针列表;由于涉及到虚函数表和虚基表,会同时增加一个(多重虚继承下对应多个)vfPtr指针指向虚函数表vfTable和一个vbPtr指针指向虚基表vbTable,这两者所占的空间大 小为:8(或8乘以多继承时父类的个数);

        6、在考虑以上内容所占空间的大小时,还要注意编译器下的“补齐”padding的影响,即编译器会插入多余的字节补齐;

        7、类对象的大小=各非静态数据成员(包括父类的非静态数据成员但都不包括所有的成员函数)的总和+ vfptr指针(多继承下可能不止一个)+vbptr指针(多继承下可能不止一个)+编译器额外增加的字节。

    非虚单继承实例如下:

    class A

    {

        char k[3];

    public:

        virtual void aa()

        {

     

        };

    };

    class B:public  A

    {

        char j[3];

    public:

        virtual void bb()

        {

           

        };

    };

    class C:public  B

    {

        char i[3];

    public:

        virtual void cc()

        {

           

        };

    };

    //一个字节   按4字节对齐

     4(指向虚函数的虚指针)+4(自己的数据成员) = 8 

     4(指向虚函数的虚指针)+4(自己的数据成员)+4(父类A的数据成员)=12   

    4(指向虚函数的虚指针)+4(自己的数据成员)+8(父类的数据成员)=16

    非虚多继承实例如下:

     

     

     

     

    重写函数f()

    Base -->char 类型

    Base1:4(指向虚函数的虚指针)+4(自己的数据成员) = 8

    Base2:4(指向虚函数的虚指针)+4(自己的数据成员) = 8

    Base3:4(指向虚函数的虚指针)+4(自己的数据成员) = 8

    Derive: 4(Base1指向虚函数表的虚指针)+4(Base1继承的成员变量)+4(Base2指向虚函数表的虚指针)+4(Base2继承的成员变量)+3(Base1指向虚函数表的虚指针)+4(Base3继承的成员变量)+4(自己的数据成员)=28

    1)虚函数表在最前面的位置。

    2)成员变量根据其继承和声明顺序依次放在后面。

    3)每个父类都有自己的虚表。

    4)子类的成员函数被放到了第一个父类的表中。

    5)内存布局中,其父类布局依次按声明顺序排列。

    6)每个父类的虚表中的f()函数都被overwrite成了子类的f()。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

     

    非虚继承的钻石继承:

     

     

     

       红色的部分就是重复的部分,就会造成二义性

     

    虚继承的钻石继承:

     

     

     

     

         可以看出,少了重合的部分。但是,代价是增加了一个虚基类指针vbptr。

  • 相关阅读:
    初探diskstats
    JVM参数简述
    304 Not Modified 简述
    vmstat命令
    iostat 工具分析I/O性能
    git添加公钥后报错sign_and_send_pubkey: signing failed: agent refused operation
    Mysql ibdata1简述
    Mysql 事务日志(Ib_logfile)
    django项目一:基于django2.2可重用登录与注册模块-前端页面配置
    django项目一:基于django2.2可重用登录与注册模块-url路由和视图
  • 原文地址:https://www.cnblogs.com/BEN-LK/p/10720337.html
Copyright © 2011-2022 走看看