抽象虚函数的 vtable 中有多少条目?

How many entries are in a vtable for an abstract virtual function?

我读到摘要 class 仍然可以有 table。但我对它的 vtable 中会有多少条目感到困惑。例如,如果我的摘要 class 是:

class Circle(){
    virtual void draw() = 0;
}

那么它的 vtable 中会有多少条目?另外,我说这个摘要 class 在它的 vtable 中有 1 个条目是否正确?感谢您的帮助。

class Circle(){
    virtual double a{ return 0.0; }
    virtual void draw() = 0;
}

每个虚函数都可以被覆盖。编译器必须建立某种机制来动态分派对每个虚函数的调用,以便代码调用正确的覆盖版本,这取决于对象的实际类型。该机制通常是一个 vtable,每个虚拟函数都必须有一个条目。所以第一个例子有一个条目,第二个例子有两个。请注意,将函数标记为纯虚拟不会影响这一点;它仍然必须动态调度。

首先,vtables 是一个实现细节。只要你不是在做非常奇怪的事情,你就应该忽略它们的存在。

其次,尽管所有编译器都使用 vtables 来实现虚拟分派,但它们的实现方式存在差异。对于某些人来说,vtable 条目只是一个函数指针;对于其他人,它是一个指针和一个偏移量。有些编译器有一个虚拟析构函数条目,有些有两个,甚至更多。有些人为协变覆盖函数添加了一个新条目,而其他人可能不会。

总的来说,您不应该担心这个问题。如果您对实现细节感兴趣,您可以阅读 Itanium C++ ABI,这是 Linux 编译器通常遵循的内容。

好吧,vtables 是一个 implementation-detail,虽然无处不在。

因为Circle的ctor-body和dtor-body都没有调用它的任何函数,尤其是none调用了虚函数,而且由于是纯虚函数所以是抽象的函数,Circle 的 vtable 永远不会被使用,如果它实际上被创建的话。

无论如何,理论上的 vtable 至少需要一个条目用于 std::type_info 和任何其他支持 dynamic_cast,每个虚函数一个,如果 dtor 是虚拟的,则两个(一个只用于 dtor,一个用于 dtor + 释放 delete).

第二个示例至少有 3 个条目(2 个虚拟函数 + RTTI)。