3

考虑下面的代码片段:

class A
{
};

class B:public virtual A
{
};

class C:public virtual A
{
};

class D:public B,public C
{
};

int main()
{
    cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C)<<" "<<sizeof(D));
    return 0;
}

我得到的输出为:

1 4 4 8

由于. B_ C_ vptr这是否意味着它virtual table是为类B和创建的C?怎么样A

一般来说,编译器究竟为哪些类创建了virtual table菱形继承?
创建虚拟表的决定是编译器特定的吗?

请在上述示例或任何其他更好示例的上下文中回答。

4

4 回答 4

0

将为 B、C 和 D 创建虚拟表。B 和 C 将各有一个 VPTR,而 D 将有 2 个 VPTR。一个指向 VTable 的 B 部分,另一个指向 VTable 的 C 部分。

注意:VTable 不是强制性的,只要可以正确建模继承关系,编译器就可以提供自己的实现。(然而大多数编译器都实现了 VTables)

于 2012-07-30T10:21:38.840 回答
0

没有什么说编译器必须为任何类创建一个vptr。也就是说,在现实生活中编译器生成vptrs 有两个原因:

  1. 虚拟调度(明显)
  2. RTTI,例如dynamic_cast(不那么明显)所要求的

通常,vtable类中的条目将指向某种“类型信息”结构,该结构为 RTTI 工作提供了足够的信息。

正是这些相同的信息使编译器能够计算出如果您将任何一个B*, C*, D*to A*, so forBCa都强制转换的话该怎么做vptrD简单地聚合它们。

于 2012-07-30T10:22:35.313 回答
0

是的,具有虚拟基础的类需要某种类型的 vtable 或等价物。您需要一些机制来在运行时查找实际的基础子对象!(请记住,虚拟基础子对象是最派生对象的职责,而不是直接继承对象的职责。)

于 2012-07-30T10:18:02.927 回答
0

如果编译器生成 VTABLES,他将为任何需要的类(包含虚函数,...)。

A不需要 VTABLE => size == 1 [最小尺寸]

B需要一个 => 大小 == 4 [你在 32 位...]

C也需要一个 => 大小 == 4

D也需要一个 => 大小 == 8(2 个条目,每个 VTABLE D 引用一个)

于 2012-07-30T10:20:09.250 回答