关于C ++虚拟继承的问题

时间:2012-10-31 11:24:58

标签: c++ inheritance virtual

以下代码来自“Inside the C ++ object model”

#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的内存布局吗?

谢谢!

4 个答案:

答案 0 :(得分:6)

  1. 当类为空时编译新的一个char,因此它可以生成不同的对象
  2. sizeof(Y)= 4,因为它是虚拟继承,构造将生成vptr表,这是32位系统上的4个字节
  3. 如果您在properties-&gt; C / C ++ / Command中使用visual studio使用/ d1reportAllClassLayout来生成对象布局 Y类对象布局将在Visual Studio上:
  4. 由Stanley B. Lippman撰写的“Inside C ++对象模型”一书非常清楚地解释了
  5.  
            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

答案 1 :(得分:1)

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

A保存虚拟表中的两个条目, 一个为Y. 其他为Z

所以两个指针的大小,即8.

Y和Z hold两者在其虚拟表中都有一个X条目,因此大小为4.

答案 2 :(得分:1)

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

继承树将如下所示:

  X
 / \
 Y Z
 \ /
  A

答案 3 :(得分:0)

类 - 必须至少为1个字节的原因是我们有一个X数组。如果它们是0个字节,那么&amp; array [1]将具有与&amp; array [3]相同的地址,其中没有人如果你不得不编写代码来检查它并且通常没有任何意义,那么会期望,会破坏代码,会很烦人。

Y只是

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

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