自由小菜园 2022-10-09 09:57 采纳率: 66.7%
浏览 36
已结题

C++菱形虚继承,为什么基类是排在内存最高位地址中?

C++有个菱形的虚继承,我看不管是MSVC还是GCC都是把最上面的基类,排在了内存的最高位,这是有什么好处吗?

img

就像这个继承图,如果定义了一个G对象,那么在内存中排序从低到高依次是 S1变量,S2变量 ,G变量,B变量
但是为什么不是基类B变量排最前面呢?

  • 写回答

2条回答 默认 最新

  • _GX_ 2022-10-09 10:54
    关注

    因为虚基类不管继承多少次,在派生对象中只能有一个子对象。如果把它放到前面的话,多继承时就会出现多个虚基类子对象。因此虚基类子对象是放在所有子对象之后的。

    https://en.cppreference.com/w/cpp/language/derived_class

    For each distinct base class that is specified virtual, the most derived object contains only one base class subobject of that type, even if the class appears many times in the inheritance hierarchy (as long as it is inherited virtual every time).

    https://stackoverflow.com/questions/6258559/what-is-the-vtt-for-a-class

    // The Diamond: Single Copies of Virtual Bases
    
    class A {
    public:
      int a;
      virtual void v();
    };
    
    class B : public virtual A {
    public:
      int b;
      virtual void w();
    };
    
    class C : public virtual A {
    public:
      int c;
      virtual void x();
    };
    
    class D : public B, public C {
    public:
      int d;
      virtual void y();
    };
    
                                       +-----------------------+
                                       |   20 (vbase_offset)   |
                                       +-----------------------+
                                       |     0 (top_offset)    |
                                       +-----------------------+
                                       | ptr to typeinfo for D |
                          +----------> +-----------------------+
    d --> +----------+    |            |         B::w()        |
          |  vtable  |----+            +-----------------------+
          +----------+                 |         D::y()        |
          |     b    |                 +-----------------------+
          +----------+                 |   12 (vbase_offset)   |
          |  vtable  |---------+       +-----------------------+
          +----------+         |       |    -8 (top_offset)    |
          |     c    |         |       +-----------------------+
          +----------+         |       | ptr to typeinfo for D |
          |     d    |         +-----> +-----------------------+
          +----------+                 |         C::x()        |
          |  vtable  |----+            +-----------------------+
          +----------+    |            |    0 (vbase_offset)   |
          |     a    |    |            +-----------------------+
          +----------+    |            |   -20 (top_offset)    |
                          |            +-----------------------+
                          |            | ptr to typeinfo for D |
                          +----------> +-----------------------+
                                       |         A::v()        |
                                       +-----------------------+
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 10月25日
  • 已采纳回答 10月17日
  • 创建了问题 10月9日

悬赏问题

  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助