【问题标题】:Can the class have more than one vtable?类可以有多个 vtable 吗?
【发布时间】:2014-03-26 17:21:02
【问题描述】:

比如说,我们有这样的类继承

class A
{
    int a;
public:
    A(){}
    virtual void f1(){}
};

class B
{
    int b;
public:
    B(){}
    virtual void f2(){}
    virtual void f3(){}
};

class C: public A, public B
{
    int c;
public:
    C(){}
    virtual void f1(){}
    virtual void f2(){}
    virtual void f3(){}
    virtual void f4(){}
};

还有对象: C c;

在对象 c 中,我们有一个 vtable 的 vptr,由 A+C 的方法组成,另一个 vtable 由 B 的方法组成。例如 x64 构建:

  • +0: vtable A+C
  • +8: int a + 填充到 8 字节
  • +16:vtable B
  • +24: int b + 填充到 8 字节
  • +32: int c + padding to 8 byte

Class C 有两个 vtable 实例:

  1. 用于调用自己的虚方法和 A 的重写方法
  2. 用于 B 的调用覆盖方法

我对这样的说法感到困惑,如果一个类是多态的,那么它就有一个 vtable

【问题讨论】:

  • 我没有找到问题。您想知道您的陈述是否正确吗?我不相信。
  • 你在回答你自己的问题,答案是肯定的……

标签: c++ visual-c++ vtable


【解决方案1】:

C++ 标准没有说明这应该如何实现。这取决于编译器是否通过使用多个 vtable 来组合 vtable [以这样一种方式,它们可以再次“拆分”,因为 C 必须可以再次变成 B 类型的对象] .

在编译器中使用多个 vtable 是相当常见的解决方案,因此您至少会在 MS 的 VC++、GNU 的 g++、LLVM/clang++ 和 ARM 的 armcc++ 中看到这种解决方案。因为我不知道它在其他编译器中是如何工作的,所以我不能说其他编译器是否使用这种方法(很可能)。

需要明确的是,这是一种流行的方法,但标准并没有说明应该如何完成。

将来,这可能会改变 - 有人可能会提出更好的不同解决方案(根据更好的定义 - 例如占用更少的空间,访问速度更快等)

【讨论】:

  • 所以,这很正常,创建了 4 个 vtable:A::vtable、B::vtable、C::vtable1(覆盖 A+自己的 C 虚拟方法)、C::vtable2 (覆盖 B)?
  • 是的,每个引入新虚函数的类都必须有它自己的 vtable [或其他一些允许该类唯一标识虚函数的构造 - vtable 只是最常见的解决方案, C++ 标准除了“它以所描述的方式工作”之外不需要任何特定的解决方案——编译器设计如何决定这样做是编译器设计者完全免费的]。
猜你喜欢
  • 1970-01-01
  • 2012-09-11
  • 2010-11-01
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多