【问题标题】:Virtual Table C++虚拟表 C++
【发布时间】:2011-01-11 12:33:42
【问题描述】:

我读到很多人写“一个虚拟表存在于一个类中,该类中声明了一个虚函数”。

我的问题是,vtable 是否仅存在于具有虚函数的类,或者它也存在于从该类派生的类。

例如

class Base{
    public:
        virtual void print(){cout<<"Base Print\n";}
};
class Derived:public Base{
    public:
        void print(){cout<<"Derived print\n";}
};

//From main.cpp 
Base* b = new Derived;
b->print();

问题:如果没有用于派生类的 vtable,那么输出就不会是“派生打印”。因此,IMO 对于任何声明了虚函数的类以及从该类继承的类都存在一个 vtable。这是正确的吗?

【问题讨论】:

标签: c++ derived-class virtual-functions vtable


【解决方案1】:

就仅考虑特定于虚函数的功能而言,在实现 vtable 的传统方法中,派生类需要单独版本的 vtable当且仅当派生类覆盖至少一个虚函数。在您的示例中,Derived 覆盖了虚函数 print。由于Derived有自己的print版本,所以Derivedvtable中的对应条目与Basevtable中的对应条目不同。这通常需要为Derived 创建一个单独的vtable。

如果Derived 根本没有覆盖任何东西,在形式上它仍然是一个单独的多态类,但为了使其虚函数正常工作,我们可以简单地将Base vtable 重用于Derived .因此,从技术上讲,Derived 不需要单独的 vtable。

然而,在实际实现中,我们通常称为“vtable”的数据结构通常还包含一些额外的特定于类的信息。这些额外的信息是如此特定于类,以至于大多数时候不可能在层次结构中的不同类之间共享 vtable,即使它们使用相同的一组虚函数。例如,在一些实现中,存储在每个多态对象中的 vtable 指针指向还存储关于类的所谓“RTTI 信息”的数据结构。出于这个原因,在大多数(如果不是全部)实际实现中,每个多态类都有自己的 vtable,即使存储在这些表中的虚函数指针碰巧是相同的。

【讨论】:

  • @AndreyT:你知道一些网页可以很好地解释与 C++ 的vtable 相关的概念吗?我试图弄清楚为什么需要一个 vtable,以及它是如何实现的。
  • @Lazer 实现细节未指定。该表是必需的,因此在运行时系统知道要调用哪个版本的多态函数(这在编译时无法确定;考虑对基类指针的操作 - 如果指针指向派生类或基类的实例)。见en.wikipedia.org/wiki/Virtual_method_table
【解决方案2】:

是的,这是真的。实际上,给定 base 的定义:

class derived:public base{
public:
 void print(){cout<<"derived print\n";}
};

完全等价于:

class derived:public base{
public:
 virtual void print(){cout<<"derived print\n";}
};

...因为您已经在 base 中将 print 定义为 virtual。

我希望编译器会强制执行...

【讨论】:

  • 也很奇怪,可以将带有void print()的基类和带有virtual void print()的派生类编译在一起..
【解决方案3】:

是的,你的理解是正确的。任何具有带有任何虚函数的基类的类都有一个 vtable。

【讨论】:

    【解决方案4】:

    是的,这是真的。类从其基类继承所有数据成员,包括 vtable。但是,vtable 条目会相应调整(例如,如果类覆盖了基类的虚拟方法,则 vtable 中的相应条目必须指向其自己的实现)。

    但请记住,“vtable”的概念是几乎每个编译器都使用的常见做法,但它不是强制性的,也不是标准化的。

    【讨论】:

    • vtable 不是成员或任何类似成员的东西。你是说vptr吗?
    猜你喜欢
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    相关资源
    最近更新 更多