深入c++对象之data语意学

    xiaoxiao2021-03-25  95

    一:

    class  x{};

    class y:public virtual x{};

    class z:public virtual x{};

    class A:public y,public z{};

    1. sizeof(x)=1,虽然x为空类,但是编译器会为其分配一个字节,用来区分x所创建对象。

      例如: x t1;  x t2;   如果没有这个字节,就无法区分t1和t2了,加上这个字节就完美解决这个问题了。

    2.  sizeof(y)=4,sizeof(z)=4;因为为虚继承,所以y,z必须分配一个虚拟函数表(vptr)是四字节(32位机器)。

    3.  sizeof(A)=8;因为y是4字节,z是四字节,所以为8字节。

    二:

    nested type 声明 放在class的起始处,不然达不到你预料的结果。

    三:

    data member 在类对象中的内存排列顺序一般是和其声明顺序相同的。vptr一般在data member的后面。他们在一个连续区块。

    四:对象和指针对data member的存取有重大差异吗?

       如:X a,*b;   a.data和b->data 有什么差异?

      1.Static Data Member   对象和指针对Static Data Member的存取没有什么差异,因为static是存储在全局数据区,直接调用就可以。(即使是base class 的data member 也是一样)。

      2.Nonstatic Data Member 的情况就比较复杂了,这就要知道它们在内存中的分配才能理解。

       先说一个简单的:非虚拟继承的单继承或多重继承单链,或其data member 是在编译器对象的地址加上数据的偏移量的。

       例如:a.data=0;   等价于   &a+(&X::data-1);(注:减1操作说明。指向data member 的指针,其offset总是被加上1,这样可以使编译系统区分出“一个指向data member 的指针用以指向class的第一个member”和“一个指向data member的指针没有指出任何member”两种情况)。

    五:继承与data member

    下面我们就来讨论情况复杂的存取情况吧(搞懂这部分瞬间觉得提升了一个level,下面的图片均来自深度探索c++模型)

    1.只要继承不要多态,布局如下图:

    2. 加上多态:

    3.多重继承:

    4.虚拟继承:

    转载请注明原文地址: https://ju.6miu.com/read-24228.html

    最新回复(0)