vptr -- 虚函数表指针
vtbl -- 虚函数表
问题1> vptr是否与类的对象相关联?
问题2> vtbl是否与类相关联?
问题3> 它们如何共同工作?
谢谢
vptr -- 虚函数表指针
vtbl -- 虚函数表
问题1> vptr是否与类的对象相关联?
问题2> vtbl是否与类相关联?
问题3> 它们如何共同工作?
谢谢
vptr
和vtbl
是实现定义的,C++标准甚至没有提到它们。然而,大多数已知的编译器都通过vptr
和vtbl
实现动态分派。
问题1: vptr
是否与类的对象相关联?
是的vptr
与包含至少一个
虚拟成员函数的类的对象相关联。编译器会在每个多态化
(包含至少一个虚拟成员函数)类的对象中添加Vptr。然后this
指针的前4个字节指向vptr
。
问题2: vtbl
是否与类相关联?
是的Vtbl
与一个类相关联。每个多态化
类都会创建一个vtbl
。
问题3: 它们如何一起工作?
编译器为每个多态类的对象添加一个vptr
,并为该类创建一个vtbl
。vptr
指向vtbl
。vtbl
包含该类中所有虚拟函数的地址列表。如果派生类覆盖了基类的虚拟函数,则在vtbl
中该特定函数的地址条目将被覆盖为覆盖的函数的地址。在运行时,编译器基于指针内部的地址而不是指针类型遍历特定类(基类或派生类)的vtbl
,并调用vtbl
中的函数地址。因此实现了动态多态。fetch
(获取this内的vptr指针) fetch
(从vtbl函数列表中获取函数地址) Call
(调用该函数)call
(直接调用函数)相对。
vptr
放在对象开头是常见的做法,但并非普遍适用。特别地,在具有非多态基类的多态派生类中时,vptr
可能会跟随该基类子对象。 - MSalters