自由小菜园 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日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效