为什么虚拟关键字会增加派生类的大小? [英] Why does virtual keyword increase the size of derived a class?

查看:87
本文介绍了为什么虚拟关键字会增加派生类的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类,一个是基类,另一个是从基类派生的:

I have two classes - one base class and one derived from it :

class base {

 int i ;

  public :
  virtual ~ base () { }
};

class derived :  virtual public base { int j ; };

main()

{ cout << sizeof ( derived ) ; }

这里的答案是16.但是,如果我改为使用非虚拟公共继承或使基类为非多态的,则答案为12,即如果这样做:

Here the answer is 16. But if I do instead a non-virtual public inheritance or make the base class non-polymorphic , then I get the answer as 12, i.e. if I do :

class base {

 int i ;

 public :
virtual ~ base () { }
};

class derived :  public base { int j ; };

main()

{ cout << sizeof ( derived ) ; }

OR

class base {

int i ;

public :
~ base () { }
};

class derived :  virtual public base { int j ; };

main()

{ cout << sizeof ( derived ) ; }

在两种情况下答案都是12.

In both the cases answer is 12.

有人可以解释一下为什么在第一种情况和其他两种情况下派生类的大小有所不同吗?

Can someone please explain why there is a difference in the size of the derived class in 1st and the other 2 cases ?

(如果有人真的需要,我会研究code :: blocks 10.05)

( I work on code::blocks 10.05, if someone really need this )

推荐答案

虚拟继承的目的是允许共享基类.问题出在这里:

The point of virtual inheritance is to allow sharing of base classes. Here's the problem:

struct base { int member; virtual void method() {} };
struct derived0 : base { int d0; };
struct derived1 : base { int d1; };
struct join : derived0, derived1 {};
join j;
j.method();
j.member;
(base *)j;
dynamic_cast<base *>(j);

最后4行都是模棱两可的.您必须明确地希望将基址派生在派生0内,还是将基团派生于派生的1.

The last 4 lines are all ambiguous. You have to explicitly whether you want the base inside the derived0, or the base inside derived1.

如果按如下方式更改第二行和第三行,问题就消失了:

If you change the second and third line as follows, the problem goes away:

struct derived0 : virtual base { int d0; };
struct derived1 : virtual base { int d1; };

您的j对象现在仅具有一个基数副本,而没有两个副本,因此最后4行不再含糊不清.

Your j object now only has one copy of base, not two, so the last 4 lines stop being ambiguous.

但是请考虑必须如何实施.通常,在派生0中,d0在m之后,而在派生1中,d1在m之后.但是通过虚拟继承,它们都共享相同的m,因此,不能让d0和d1紧随其后.因此,您将需要某种形式的额外间接.这就是多余的指针来自的地方.

But think about how that has to be implemented. Normally, in a derived0, the d0 comes right after the m, and in a derived1, the d1 comes right after the m. But with virtual inheritance, they both share the same m, so you can't have both d0 and d1 come right after it. So you're going to need some form of extra indirection. That's where the extra pointer comes from.

如果您想确切地知道布局是什么,则取决于目标平台和编译器.仅仅"gcc"是不够的.但是对于许多现代的非Windows目标,答案是由Itanium C ++ ABI定义的,该文件记录在 http://mentorembedded.github.com/cxx-abi/abi.html#vtable .

If you want to know exactly what the layout is, it depends on your target platform and compiler. Just "gcc" isn't enough. But for many modern non-Windows targets, the answer is defined by the Itanium C++ ABI, which is documented at http://mentorembedded.github.com/cxx-abi/abi.html#vtable.

这篇关于为什么虚拟关键字会增加派生类的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆