C++ -- 对象或类关联vptr和vtbl?

6

vptr -- 虚函数表指针

vtbl -- 虚函数表

问题1> vptr是否与类的对象相关联?

问题2> vtbl是否与类相关联?

问题3> 它们如何共同工作?

谢谢

2个回答

10
vptrvtbl是实现定义的,C++标准甚至没有提到它们。然而,大多数已知的编译器都通过vptrvtbl实现动态分派。 问题1: vptr是否与类的对象相关联? 是的
vptr与包含至少一个虚拟成员函数的类的对象相关联。编译器会在每个多态化(包含至少一个虚拟成员函数)类的对象中添加Vptr。然后this指针的前4个字节指向vptr问题2: vtbl是否与类相关联? 是的
Vtbl与一个类相关联。每个多态化类都会创建一个vtbl问题3: 它们如何一起工作? 编译器为每个多态类的对象添加一个vptr,并为该类创建一个vtblvptr指向vtblvtbl包含该类中所有虚拟函数的地址列表。如果派生类覆盖了基类的虚拟函数,则在vtbl中该特定函数的地址条目将被覆盖为覆盖的函数的地址。在运行时,编译器基于指针内部的地址而不是指针类型遍历特定类(基类或派生类)的vtbl,并调用vtbl中的函数地址。因此实现了动态多态
这种动态多态的成本是:
fetch (获取this内的vptr指针) fetch (从vtbl函数列表中获取函数地址) Call (调用该函数)
与静态绑定的call(直接调用函数)相对。

1
vptr放在对象开头是常见的做法,但并非普遍适用。特别地,在具有非多态基类的多态派生类中时,vptr可能会跟随该基类子对象。 - MSalters

4
虚表指针是类中每个对象内部的指针,指向正确的虚表。虚表中包含类的虚函数的地址。当通过基类指针调用函数时,编译器遍历虚表以获取正确的函数。

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