2012-10-31 158 views
9

以下代码的问题是从书约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) “C++对象模型内部”,则输出为:

我这里还有我的问题

1的sizeof(X)= 1

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

2,的sizeof(Y)= 4

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

谢谢!

+0

每个问题一个问题请 –

+0

第一个问题,检查:http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an- rq = 1 –

+1

我认为你的主要问题是,因为Y使用虚拟继承来从非多态类X派生,而Y本身是非多态的,所以虚拟继承本身会导致Y有一个V表,因此它的大小是4 .. – CashCow

回答

6
  1. 编译新的炭类时是空的,所以它可以产生不同的对象
  2. 的sizeof(Y)= 4,因为它是虚拟如果在属性 - > C/C++/Command中使用visual studio use/d1reportAllClassLayout生成对象布局 类Y对象布局将在Visual上工作室:
  3. 书“里面C++对象模型”由Stanley B.李普曼解释这个非常好


     class Y size(4): 
      +--- 
      0  | {vbptr} 
      +--- 
      +--- (virtual base X) 
      +---
Y::[email protected]: 0 | 0 1 | 4 (Yd(Y+0)X)

vbi: class offset o.vbptr o.vbte fVtorDisp X 4 0 4 0
1

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

A持有在虚拟表中的两个条目, 一个用于Y 其他对于z

所以的sizeof两个指针即8.

Y和Z都保持在具有X的单个条目他们的虚拟表,因此尺寸为4

+0

我没有在这里看到称为B和C的类 – CashCow

1

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

继承树的样子:

X 
/\ 
Y Z 
\/
    A 
0

类-must-至少有1个字节的原因是说,我们有十数组如果它们是0字节,那么& array [1]的地址与& array [3]的地址相同,这是没人会想到的,会破坏代码,如果你必须编写代码来检查代码,通常不会造成干扰任何意义。

Y就应该仅仅是

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

你能想到的虚函数表(虚拟指针类和虚拟函数)为静态变量,你不能用手/代码编辑(或至少不应该)。把它想象成编译器保留的静态变量

+1

我喜欢这个解释,原因是sizeof(X)= 1 – Junjie