我读到一个抽象类仍然可以有一个表。但我对它在vtable中会有多少条目感到困惑。例如,如果我的抽象类是:
class Circle(){
virtual void draw() = 0;
}
然后它的vtable中有多少个条目?另外,我是否正确地说这个抽象类在其vtable中有1个条目?谢谢你的帮助。
class Circle(){
virtual double a{ return 0.0; }
virtual void draw() = 0;
}
答案 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)。