【问题标题】:Questions about C++ virtual Inheritance关于 C++ 虚继承的问题
【发布时间】:2012-10-20 20:15:39
【问题描述】:

以下代码来自《深入了解C++对象模型》一书

#include <iostream>  
using namespace std;
class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};

int main()
{
     cout<<sizeof(X)<<" "<<sizeof(Y)<<" "<<sizeof(Z)<<" "<<sizeof(A)<<endl;
     return 0;
}

在我的电脑(Windows,VS2010)中,输出为:

1 4 4 8

这是我的问题

1, sizeof(X)=1

书上说当 X 类型生成两个实例时,比如说 xa 和 xb。编译在 A 中插入一个字节,以便 xa 和 xb 可以具有不同的地址。我不太明白其中的原因。

2, sizeof(Y)=4

通过使用虚拟继承,我们会有一个额外的虚拟指针吗?我想这可能与多态中的虚拟指针不同。谁能给我 Y 的内存布局?

谢谢!

【问题讨论】:

  • 每个问题一个问题
  • 第一个问题,检查:stackoverflow.com/questions/621616/…
  • 我认为您的主要问题是,因为 Y 使用虚拟继承从非多态类 X 派生,并且 Y 本身是非多态的,所以虚拟继承本身是否会导致 Y 具有 v-表因此它的大小是 4..

标签: c++ inheritance virtual


【解决方案1】:
  1. 当类为空时编译新一个字符,因此可以生成不同的对象
  2. sizeof(Y)=4 因为是虚拟继承,构造会生成vptr表,在32位系统上是4字节
  3. 如果您使用的是 Visual Studio,请在 properties->C/C++/Command 中使用 /d1reportAllClassLayout 来生成对象布局 Y 类对象布局将在 Visual Studio 上:
  4. Stanley B. Lippman 所著的《Inside C++ object model》一书对这一点进行了很好的解释

 
        class Y size(4):
            +---
            0     | {vbptr}
            +---
            +--- (virtual base X)
            +---
Y::$vbtable@: 0 | 0 1 | 4 (Yd(Y+0)X) vbi: class offset o.vbptr o.vbte fVtorDisp X 4 0 4 0

【讨论】:

    【解决方案2】:

    空类的 sizeof 总是返回 1。这是空类的单个虚拟字节。

    A 持有虚拟表中的两个条目, 一个为 Y 其他为 Z

    所以两个指针的大小即8。

    Y 和 Z 在它们的虚拟表中都有一个 X 条目,因此大小为 4。

    【讨论】:

    • 我在这里没有看到名为 B 和 C 的类
    【解决方案3】:

    一个 A 对象将包括一个 Y 对象、一个 Z 对象(按此顺序)和只有 一个 X 对象(由 Y 和 Z 中的指针引用),因为 Y 和 Z 实际上都继承自X,因此意味着当多重继承开始发挥作用时,只有一个 X 对象将在子类中实例化。 A 仍然有两个对象(一个 Y,一个 Z),因此 sizeof = 8(因为它们的 sizeof = 4)。但是 Y 和 Z 中指向 X 对象的指针都会指向同一个地址。

    继承树如下所示:

      X
     / \
     Y Z
     \ /
      A
    

    【讨论】:

      【解决方案4】:

      类 - 必须 - 至少 1 个字节的原因是说我们有一个 X 数组。如果它们是 0 个字节,那么 &array[1] 将具有与 &array[3] 相同的地址,这是没有人会想到的,破坏代码,如果您必须编写代码来检查它会很烦人,而且通常没有任何意义。

      Y 就是

      static void* virtual_ptr1 //note this is in virtual table and cannot be edited  
      

      您可以将 vtables(指向类和虚函数的虚拟指针)视为无法手动/代码编辑(或至少不应该)的静态变量。将其视为编译器保留的静态变量

      【讨论】:

      • 我喜欢这个解释,原因是 sizeof(X)=1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 2011-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-20
      相关资源
      最近更新 更多