2013-02-21 46 views
1

我是新来的C++编程,在下面的代码中我使用虚拟继承,所以派生类的大小显示24个字节,但我没有得到它是如何,所以请帮助我究竟是如何。派生类的大小

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

class BaseClass 
{ 
     private : int a, b; 
     public : 
    BaseClass() 
    { 
    a = 10; 
    b = 20; 
    } 
    virtual int area() 
    { 
    return 0; 
    } 
}; 

class DerivedClass1 : virtual public BaseClass 
{ 
    int x; 
     public: 
    virtual void simple() 
    { 
    cout << "inside simple" << endl; 
    } 
}; 

int main() 
{ 
    DerivedClass1 Obj; 
    cout << sizeof(Obj) << endl; 
    return 0; 
} 
+0

在这种情况下,虚拟继承不起任何作用。当存在钻石形状的继承模式时,通常使用虚拟继承 - 继承B和C,B和C都继承D.如果B和C都使用虚拟继承继承D,则A仅继承D的一个共享“副本” - 否则它继承了D的两个单独的“副本”。这里只有一个基地,只能通过一条路线继承,所以不可能共享基地。即使在没有直接指向的情况下,内存布局对于虚拟或非虚拟继承仍然可能有所不同,但可能不是这种情况。 – Steve314 2013-02-21 06:32:48

+0

是啊史蒂夫我知道虚拟继承这里没有做任何事情..但我只是检查什么是派生类的大小,如果我这样做...所以请我的方式.. – nagaradderKantesh 2013-02-21 06:42:09

+0

@nagaradderKantesh - 我认为詹姆斯已经明白了。唯一的问题是,布局只是偶然*与非虚拟继承相同 - “shared”部分('BaseClass :: a'和'BaseClass :: b')大概是通过'offsetof'持有的在虚拟表中而不是在编译时知道偏移量。 – Steve314 2013-02-21 06:46:34

回答

2

我猜你正在编译为64位?在这种情况下,你的DerivedClass1可能会被在存储器布局与字节的这种布置:

offset  size type 
0   8  pointer to virtual function table 
8   4  int BaseClass::a 
12   4  int BaseClass::b 
16   4  int DerivedClass1::x 
20   4  filler, so that the total size of this class is an even number of 64-bit (8-byte) words 

指针到虚拟功能表被默默地添加到你的类由C++编译器对任何类,它是的一部分包含任何虚函数的类继承层次结构。

+0

不,我不编译为64位..我正在编译为32位,但它仍然显示24个字节...为什么这样.. – nagaradderKantesh 2013-02-21 06:36:33

+0

@ John5342 - 处理同样的事情的另一种方式是有一个'offsetof '存储在虚拟表中,因此您可以计算出在运行时从特定基部继承的块的偏移量。这可能稍微复杂一点,但会减少每个实例的大小开销。这也是我能想到解释“sizeof”价值的唯一方法,所以我认为James是对的。 – Steve314 2013-02-21 06:36:46

+0

@ John5342 - “sizeof(DerivedClass1)”必须包含“BaseClass :: a”和“BaseClass :: b”。这些成员必须存在。从DerivedClass1继承的任何类中它们的相对位置可能不同,这一事实不会改变这一点。 sizeof(DerivedClass1)'包含所有成员,即使是通过虚拟继承继承的成员。如果类'A'通过两条不同的路由继承了'BaseClass',两者都具有虚拟继承,'sizeof(A)'还将包含来自'BaseClass'的成员* 1 *副本的空间。 – Steve314 2013-02-21 06:53:31