类的大小——sizeof 的研究

本文详细解析了C++中类的大小如何计算,包括空类、含有虚函数的类及继承类的大小,并探讨了成员变量对齐规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看一个空的类占多少空间?

    class Base  
    {  
    public:  
      Base();  
      ~Base();     
    };  

注意到我这里显示声明了构造跟析构,但是sizeof(Base)的结果是1.不申明或者是用struct也是一样的,结果为1.

因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。

而析构函数,跟构造函数这些成员函数,是跟sizeof无关的,也不难理解因为我们的sizeof是针对实例,而普通成员函数,是针对类体的,一个类的成员函数,多个实例也共用相同的函数指针,所以自然不能归为实例的大小,这在我的另一篇博文有提到。
接着看下面一段代码

    class Base  
    {  
    public:  
        Base();                  
        virtual ~Base();         //每个实例都有虚函数表  
        void set_num(int num)    //普通成员函数,为各实例公有,不归入sizeof统计  
        {  
            a=num;  
        }  
    private:  
        int  a;                  //占4字节  
        char *p;                 //4字节指针  
    };  

    class Derive:public Base  
    {  
    public:  
        Derive():Base(){};       
        ~Derive(){};  
    private:  
        static int st;         //非实例独占  
        int  d;                     //占4字节  
        char *p;                    //4字节指针  

    };  

    int main()   
    {   
        cout<<sizeof(Base)<<endl;  
        cout<<sizeof(Derive)<<endl;  
        return 0;  
    }  

结果自然是
12
20

Base类里的int a;char *p;占8个字节。
而虚析构函数virtual ~Base();的指针占4子字节。
其他成员函数不归入sizeof统计。
Derive类首先要具有Base类的部分,也就是占12字节。
int d;char *p;占8字节
static int st;不归入sizeof统计
所以一共是20字节。

在考虑在Derive里加一个成员char c;

    class Derive:public Base  
    {  
    public:  
        Derive():Base(){};  
        ~Derive(){};  
    private:  
        static int st;  
        int  d;  
        char *p;  
        char c;     
    };  

这个时候,结果就变成了
12
24

一个char c;增加了4字节,说明类的大小也遵守类似class字节对齐,的补齐规则。

至此,我们可以归纳以下几个原则:
1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节。
4.类的总大小也遵守类似class字节对齐的,调整规则。
5. 子类只是共用父类的虚函数表,因此一旦父类里有虚函数,子类的虚函数将不计入sizeof大小。

.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值