C++ Data 内存布局

 

       class X{};

       class Y:virtual public X{};

       class Z:virtual public X{};

       class B:virtual public X{};

       class A:public Y,public Z,public B{};

       class M{};

       class N:virtual public X,virtual public M

       {

       };

       int main()

       {

          cout<<sizeof(X)<<endl;

          cout<<sizeof(Y)<<endl;

          cout<<sizeof(Z)<<endl;

          cout<<sizeof(A)<<endl;

          cout<<endl<<endl<<sizeof(N)<<endl;

          return 0;

       }

       Code::Block     1  4   4   12   4

       VS2008         1  4   4   12   8

 

       C++ Standard并不强制规定如“base class subobjects的排列次序”,或“不同存取层级的data member的排列次序”。

       C++对象模型尽量以空间优化和存取速度优化的考虑来表现nonstaticdata members,并且保持和C语言struct数据配置的兼容性。它把数据直接存放在每一个class object之中。对于继承而来的nonstatic data members也是如此。不过并没有强制定义其间的排列次序。

       每一个class object因此必须有足够的大小以容纳它所有的nonstatic data members。因为它可能比你想象的还大。

       1,由编译器自动加上的额外data members,用以支持某些语言特性(主要是各种virtual 特性)。

       2,因为alignment(边界调整)的需要。

 

        对member functions本身的分析,会直到整个class的声明都出现了才开始。因此,在一个inline member function躯体之内的一个datamember绑定操作,会在整个class声明完成之后才发生。

       然而,这对于member function的argument list并不为真。Argemment list中的名称还是会在它们第一次遭遇时被适当地决议完成。

       typedef intlength;

       class Point

       {

       public:

           void fun(length a)

           {

              cout<<typeid(a).name()<<endl;      //i

              cout<<typeid(_a).name()<<endl;        //f

           }

           typedef float length;

           length _a;

       };


DataMemberr的布局

       C++ Standard 要求,在同一个access section中,members的排列只需符合“较晚出现的members在class object中有较高的地址”这一条件即可,也就是说,各个members并不一定得连续排列,相对次序不会改变,什么东西可能会介于被声明的members之间呢?members的边界调整(alignment)可能 就需要填补一些bytes。编译器还可能会合成一些内部使用的data members,以支持整个对象模型。

       C++ Standard秉持先前所说的“对于内存所持的放任态度”。

       C++ Standard也允许编译器将多个access section之中的data members自由排列,不必在乎它们出现在class声明中的次序。

       每一个static data member只有一个实体,存放在程序的data segment之中。

       若取一个static data member的地址,会得到一个指向其数据类型的指针。

       如果有两个classes,每一个都声明了一个static member freelist,那么当它们都被放在程序的data segment时,就会导致名称冲突。编译器的解决方法是暗中对每一个static data member编码,名字重组(name-mangleing),以获得一个独一无二的程序识别代码。

       Nonstatic datamembers直接存放在每一个classobject之中。除非经由明确的或暗喻的classobject,没有办法直接存取它们。

       欲对一个nonstatic data member进行存取操作,编译器需要把class

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值