C++中的每个类是否都有虚函数表

3

在C++中,每个类都有虚函数表吗?

我知道虚表是用于实现多态的。拥有虚函数的类必须有虚表。但是如果一个类没有虚函数呢?或者这个类没有基类呢?


2
相关:https://dev59.com/g1vUa4cB1Zd3GeqPs10g 所以简短的回答是不行。 - Mysticial
标准没有规定这个。 - Martin York
@LokiAstari:不是的,但标准确实指定了哪些类是多态的,在合理的实现中,这些类将是唯一具有虚函数表或等效物的类。 - Mike Seymour
@MikeSeymour:是的,我有点迂腐。但我的意思是标准没有规定多态如何影响类的布局(如果有的话)。 - Martin York
可能是重复的问题:编译器是否为所有类创建Vtable? - Bergi
4个回答

6
C++的语言规范并没有定义"vtable"是什么,以及哪些类需要它。
编译器中特定的C++实现通常使用vtable来实现虚方法。如果一个类没有虚方法(也没有带有虚方法的超类),那么编译器可能会省略vtable。但请记住,这仅仅是编译器实现决策,并不是标准要求。

2
澄清一下,如何实现虚拟是由实现定义的,但标准布局类型的规则非常严格,编译器的自由度很小。也就是说,标准布局类型不能包含虚函数表,否则会违反标准布局的规则。 - edA-qa mort-ora-y
@edA-qamort-ora-y:我不确定那是否正确。显然你不能把vptr作为第一个成员(第一个声明的成员必须在偏移量0处),但这是我所看到的唯一问题。 - MSalters
我不相信你可以有任何特殊数据。请考虑,允许在布局兼容类型之间进行memcpy,也可以通过中间字符缓冲区进行复制。如果此附加值以某种方式标识了类,则通过memcpy复制它将基本上破坏目标类型,因为其特殊值将与类所期望的不匹配。如果绝对没有使用此值,那就没问题了,但这将与未命名填充完全相同。 - edA-qa mort-ora-y
那么你的意思是有更好的方法来做吗? - jokoon

3
作为一个非标准的经验法则(vtables并不是由标准规定的),它适用于几乎所有编译器:
只有具有虚成员函数和/或虚析构函数的类才有vtable,其他类则没有。这符合C++中“按需付费”的一般规则。
当然,这也给您带来了一个重要的责任:您的类是否需要多态地删除?即,它将作为公共基类使用并通过它进行删除吗?那么请将析构函数声明为虚函数。

2

C++语言本身并不规定虚函数的实现方式,可以使用vtable或其他机制。但通常情况下,它是通过v-table来实现的,只有当类包含虚函数时才会创建这个v-table。


1

v-table 中保存函数的地址。这个表将保存在基类中定义的所有虚函数的函数地址。 根据实际对象类型,此地址会发生变化并调用确切的函数。

如果类没有继承任何具有虚函数的类,则不需要保存任何v-table。所有函数调用都将在编译时链接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接