Nar*_*uto 4 c++ virtual vtable
我对虚拟表有一点疑问,每当编译器遇到类中的虚函数时,它就会创建Vtable并在那里放置虚函数地址.对于继承的其他类,它也会发生类似的情况.它是否在每个类中创建一个指向每个Vtable的新指针?如果不是,当创建派生类的新实例并将其分配给Base PTR时,它如何访问Virtual函数?
每次创建包含虚函数的类,或者从包含虚函数的类派生时,编译器都会为该类创建唯一的VTABLE.
如果不覆盖在基类中声明为virtual的函数,则编译器将使用派生类中基类版本的地址.
然后它将VPTR放入类中.使用简单继承时,每个对象只有一个VPTR.必须初始化VPTR以指向相应VTABLE的起始地址.(这发生在构造函数中.)一旦VPTR初始化为适当的VTABLE,实际上该对象"知道"它是什么类型.但是,除非在调用虚函数时使用它,否则这种自我知识就毫无价值.当您通过基类地址调用虚函数时(编译器没有执行早期绑定所需的所有信息的情况),会发生一些特殊情况.编译器生成不同的代码来执行函数调用,而不是执行典型的函数调用,它只是对特定地址的汇编语言CALL.
对于每个具有虚函数的类,都会创建一个虚函数表。然后,当使用构造函数创建具有可行对象的类的对象时,构造函数会将适当的 vtable 复制到该对象中。因此,每个对象都有一个指向其 vtable 的指针(或者在多重继承的情况下,必要时,有一个指向其每个 vtable 的 Orr。)。编译器知道vtable在对象中的位置,因此当需要调用虚方法时,它会输出字节码来阻止vtable,查找适当的方法并跳转到其地址。
在单继承的简单情况下,子类从父类的 vtable 的副本开始,然后为子类中重写父类方法的每个虚拟方法获取重写条目。(并且它还为子包中不重写父类方法的每个虚拟函数获取一个新条目)