3.2 Data Member的布局

一、预热

在讨论Data Member布局之前,先看比较常见的笔试题目:
1、 空class

    class X{};

sizeof(X) : 1。空的class中没有任何data member,大小不应该是0吗?大小之所以为1,是因为编译器安插进去一个char,所以空class实际上隐藏1字节的大小。
2、没有virtual 成员函数的class

class Point3d
{
public:
    // ...
private:
    float x, y, z;
};

sizeof(Point3d) : 4 + 4 + 4 = 12。float占用4个字节,该类定义了三个float类型的data member,大小为12毫无悬念。
3、含有virtual成员函数的class

class Point3d
{
public:
    virtual void vir_func() { }
private:
    float x, y, z;
};

sizeof(Point3d) : 12 + 4 = 16。其中的4个字节是怎么回事?这一点需要特别注意,编译器还可能会合成一些内部使用的data members,以支持整个对象模型。vptr就是这样的东西,目前所有的编译器都会把它(指向虚表的指针(指针占4个字节)vptr)安插在“内含virtual function之class”的object中。
4、比较混合的class

class Point3d
{
public:
    virtual void vir_func() {}
    virtual void vir_func2() {}
    void func_test() { }
private:
    float x;
    static list<Point3d*> *freeList;
    float y;
    static const int chunkSize = 250;
    float z;
};

sizeof(Point3d) : 12 + 4 = 16。哦?class Point3d含有两个virtual functions,为什么没有两个4字节被计算呢?傻啊,“指向虚表的指针vptr”在class object中只有一个,而虚表存放的是virtual functions的地址。哦?为什么没有计算static data members?又犯傻了,static member存放在data segment,不存放于class object,当然计算class占用内存大小不需要考虑进去。另外,如果想知道为什么nonstatic、non-virtual function members没有占用内存,狠戳这里

除了上面阐述的简单模型外,alignment(对齐)不可忽略,需牢记在心。下面正式讨论Data Member布局。


二、Data Member布局

在预热这一小节中,其实讨论了大部分class data members在内存中的存储,这里简单介绍,data member在内存中是如何排列(即布局)的。以下面的class为例:

class Point3d
    {
    public:
        // ...
    private:
        float x;
        static list<Point3d*> *freeList;
        float y;
        static const int chunkSize = 250;
        float z;
    };

经过第一小节的分析,该Point3d class object布局中仅有x,y和z。C++Standard要求,同一access section(也就是private、public、protected等区段)中,members的排列只需符合“较晚出现的members在class object中有较高的地址”这一条件即可。也就是说,各个members并不一定连续排列。什么东西可能会介于被声明的members之间呢?members的边界调整(alignment)可能就需要填补一些bytes,也可能是编译器合成的东西(比如:vptr),vptr传统上被放在所有显式声明的members的最后,不过如今也有一些编译器把vptr放在一个class object的最前端。

参考文献:《深度探索C++对象模型》侯捷 译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值