none
关于虚继承 RRS feed

  • 问题

  • 你好:

         代码如下:

    class base1
    {
    public:
    int v1 = 1;
    virtual void print1() {}
    };

    class base2
    {
    public :
    int v2 = 2;
    };

    class base3
    {
    public:
    int v3 = 3;
    };

    class test : public base2,virtual public base3,  public base1
    {
    public:
    int vt = 4;
    };

    运行后内存分布如下:

    请问一下为什么虚基类表vbtable在基类base2的前面?

    2020年4月15日 8:20

全部回复

  • 你好,

    感谢您在MSDN论坛发帖提问。

    >>请问一下为什么虚基类表vbtable在基类base2的前面?

    虚拟继承的子类有单独的有虚函数表。子类和父类的数据完全间隔。先存放子类自己的虚函数表和数据,最后保存父类的虚函数和数据。如果子类重写了父类的虚函数,那么则将子类内存中父类虚函数表的相应函数替换。

    Best Regards,

    Jeanine Zhang

    2020年4月15日 9:41
    版主
  • 你好:

          我还是不明白vbtable为什么在基类base2的前面,为什么不能是base1、base2,然后是vbtable呢?这样排列的依据是什么呢?

    2020年4月15日 10:28
  • 你好,

    每个包含了虚函数的类都包含一个虚表。三个基类中只有base1类有虚函数,所以只有base1类存在虚表。首先第一层存放的是base1类的第一个对象,第二层存放的是base1类的第二个对象的虚指针指向的base1类的虚表。第三层存放的是base2类的对象。第四层存放的是base3类的对象。因为tset类虚拟继承base3,所以第四次存放的是代替base3类的对象的tset类对象。第五层存放base3类的对象。

    Best Regards,

    Jeanine Zhang

    2020年4月16日 2:03
    版主
  • 你好:

         对于”第二层存放的是base1类的第二个对象的虚指针指向的base1类的虚表。“中提到的虚表是否是base1的虚函数表?如果是虚函数表那和vbtable应该是没有关系的啊?

    2020年4月16日 2:46
  • 你好,

    不好意思, 我将vbtable看成了vtable.

    vbtable(virtual base class table)虚基类表每项记录了被继承的虚基类子对象相对于虚基类表指针的偏移量。

    虚函数表中按照对象继承的顺序排列对象的虚函数地址,虚基类表中按照对象继承的顺序排列对象的直接虚继承类到虚基类的偏移。

    Best Regards,

    Jeanine Zhang


    2020年4月16日 3:26
    版主
  • 你好:

          那为什么vbtable在基类base2的前面,而不是在后面呢?

    2020年4月16日 4:32
  • 你好:

          请问为什么vbtable在基类base2的前面,而不是在后面呢?

    2020年4月17日 1:29
  • 你好,

    每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)。vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表,记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员。

    我很奇怪为什么vbtable显示在内存分布中?

    Best Regards,

    Jeanine Zhang

    2020年4月20日 3:09
    版主