自由小菜园 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 用twincat控制!
  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1
  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决