• Sizeof Class


    类的大小在面试的时候被问了, 这里记录备份一下.

    类的大小计算的时候,只包括:
    类的非静态成员数据的类型大小之和
    如果有虚函数的话,还要加上指向虚函数的指针(vptr)大小
    边缘调整后的大小
    与类中的构造函数,析构函数以及其他的成员函数无关.函数是类的所有对象共享的,而我们计算类的占用空间的时候,只计算对象占的空间

    关于成员函数访问的问题:

    内存对象模型里面仅保存变量,这里就包括指向虚表的指针,如果类定义里没有虚函数,那就没虚表什么事儿,_vprt会被优化掉,如果有,那么对象起始地址出就开始存放_vprt,如果涉及多个续表,"小伙伴,排排坐",之后的虚表指针接着第一个续表指针存放。

    对于成员函数,如果调用成员函数,编译器会负责把已经生成好的成员函数首地址给要调用的对象。类对象.function()这个过程,会在编译期间直接把function的地址给类对象(就是说,会直接或间接的生成汇编代码,让类对象去call function函数。不会把调用的过程留到运行时去解决)。 而之前我犯糊涂,总想着得对象得有个指针来着。其实不必要,因为我们不会把问题留到运行时去确定。

    我们去实验一下类大小的关系:

    class a{};
    class b{};
    class c:public a{
    };
    class d:public b,public c{
    };
    class e:public a{
        virtual void fun(){};
        void My(){};
    };
    class f:public b,public c{
        virtual void fun(){};
        void MY(){};
    };
    class g{
    public:
        int aaa;
    };
    class h{
        public:
        int aaa;
        char bbb;
        void My(){};
    };
    class i{
        public:
        int aaa;
        char bbb;
        double ccc;
    };
    class j{
        public:
        int aaa;
        static int m;
    };
    int j::m = 0;

    假设有以上几个类,我们使用sizeof输出类的大小:

      cout<<"sizeof a is : "<<sizeof(a)<<endl;
        cout<<"sizeof b is : "<<sizeof(b)<<endl;
        cout<<"sizeof c is : "<<sizeof(c)<<endl;
        cout<<"sizeof d is : "<<sizeof(d)<<endl;
        cout<<"sizeof e is : "<<sizeof(e)<<endl;
        cout<<"sizeof f is : "<<sizeof(f)<<endl;
        cout<<"sizeof g is : "<<sizeof(g)<<endl;
        cout<<"sizeof h is : "<<sizeof(h)<<endl;
        cout<<"sizeof i is : "<<sizeof(i)<<endl;
        cout<<"sizeof j is : "<<sizeof(j)<<endl;

    得到的输出结果为

    这里不难理解,a,b,c,d均没有成员变量和虚函数,这1个字节表明类的位置

    e类有一个父类,类中有一个虚表指针4个字节,大小为4

    f类有两个父类,类中有两个虚表指针,8字节,但是只有一个虚函数,而且看到内存中只有一个虚表指针的值,另一个没有值

    (注:图中地址与上图地址不符,每次调试地址均会变化)

    g类有一个成员变量占用4字节

    h类有两个变量,一个int和一个char,这里和struct一样,内存对齐,占用8字节

    i类是int,char,double排列,按8字节对齐,占用16字节

    j类只有成员变量占用空间,静态成员不占用空间,为4字节

    我们在输出对象的大小也是一样的

      a A ;
        b B ;
        c C ;
        d D ;
        e E;
        f F;
        g G;
        h H;
        i I;
        j J;
    
        cout<<"sizeof a is : "<<sizeof(A)<<"  Address of A is : "<<&A<<endl;
        cout<<"sizeof b is : "<<sizeof(B)<<"  Address of B is : "<<&B<<endl;
        cout<<"sizeof c is : "<<sizeof(C)<<"  Address of C is : "<<&C<<endl;
        cout<<"sizeof d is : "<<sizeof(D)<<"  Address of D is : "<<&D<<endl;
        cout<<"sizeof e is : "<<sizeof(E)<<"  Address of E is : "<<&E<<endl;
        cout<<"sizeof f is : "<<sizeof(F)<<"  Address of F is : "<<&F<<endl;
        cout<<"sizeof g is : "<<sizeof(G)<<"  Address of G is : "<<&G<<endl;
        cout<<"sizeof h is : "<<sizeof(H)<<"  Address of H is : "<<&H<<endl;
        cout<<"sizeof i is : "<<sizeof(I)<<"  Address of I is : "<<&I<<endl;
        cout<<"sizeof j is : "<<sizeof(J)<<"  Address of J is : "<<&J<<endl;

  • 相关阅读:
    Prince and princess「DP优化」
    Wooden Stricks——两个递增条件的线性DP
    死磕 java线程系列之线程池深入解析——构造方法
    死磕 java线程系列之线程池深入解析——体系结构
    死磕 java线程系列之自己动手写一个线程池(续)
    死磕 java线程系列之自己动手写一个线程池
    死磕 java线程系列之创建线程的8种方式
    死磕 java线程系列之线程模型
    死磕 java同步系列之终结篇
    死磕 java同步系列之redis分布式锁进化史
  • 原文地址:https://www.cnblogs.com/aliflycoris/p/5859064.html
Copyright © 2020-2023  润新知