答案 0 :(得分:16)
首先,vtables的使用是实现定义的,并非标准强制要求。
对于使用vtable的实现,答案是:通常是。您可能认为抽象类不需要vtable,因为派生类将具有自己的vtable,但在构造期间需要它:在构造基类时,它将vtable指针设置为其自己的vtable。稍后当输入派生类构造函数时,它将使用自己的vtable代替。
那就是说,在某些情况下,这是不需要的,并且vtable可以被优化掉。例如,MS Visual C ++提供了__declspec(novtable)
标志来禁用纯接口类上的vtable生成。
答案 1 :(得分:2)
这里似乎存在一种常见的误解,我认为其来源的痕迹仍然可以在网上找到。 Paul DiLascia wrote 2000年某个时候 -
......看看编译器还在 生成一个vtable 所有人 条目为NULL 并仍然生成 用于初始化vtable的代码 A的构造函数或析构函数。
那可能实际上是真的,但现在肯定不是。
是的,抽象类确实有vtable,也有纯抽象方法(实际上可以实现和调用),是的 - 它们的构造函数将纯条目初始化为指定值。至少对于VC ++,该值位于CRT函数_purecall的地址中。实际上,您可以通过overloading purecall yourself或using _set_purecall_handler控制该值。
答案 2 :(得分:-7)
我们有一个具有至少一个虚函数的类的虚拟表。 虚函数也可以是纯粹的。 这意味着。一个abstact类可以有一个vtable。
在抽象类的情况下,vtable条目将为NULL。 当你试图实例化一个抽象类时,它将检查vtable并检查是否存在NULL值。 如果存在NULL,编译器将抛出错误。