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

时间:2018-03-15 14:44:53

标签: c++ abstract-class vtable vptr

我读到一个抽象类仍然可以有一个表。但我对它在vtable中会有多少条目感到困惑。例如,如果我的抽象类是:

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

然后它的vtable中有多少个条目?另外,我是否正确地说这个抽象类在其vtable中有1个条目?谢谢你的帮助。

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

3 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:4)

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

其次,尽管所有编译器都使用vtable来实现虚拟调度,但它们的工作方式也存在差异。对某些人来说,vtable条目只是一个函数指针;对于其他人来说,它是指针和偏移量。有些编译器有一个虚拟析构函数的条目,有些有两个,甚至更多。有些人为covariantly overriden函数添加了一个新条目,而其他人可能没有。

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

答案 2 :(得分:2)

嗯,vtable是一个实现细节,虽然无处不在。

因为Circle的ctor-body和dtor-body都没有调用它的任何函数,特别是没有调用虚函数,并且由于纯虚函数Circle而是抽象的如果实际上甚至创建了vtable,那么它就永远不会被使用。

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

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