【发布时间】:2012-04-21 08:19:17
【问题描述】:
我对Virtual Table有一点疑问,每当编译器遇到类中的虚函数时,它都会创建Vtable并将虚函数地址放置在那里。对于继承的其他类,它也会发生类似的情况。它是否在每个类中创建一个指向每个 Vtable 的新指针?如果不是,当派生类的新实例被创建并分配给 Base PTR 时,它如何访问虚函数?
【问题讨论】:
-
Virtual Table C++ 的可能重复项
我对Virtual Table有一点疑问,每当编译器遇到类中的虚函数时,它都会创建Vtable并将虚函数地址放置在那里。对于继承的其他类,它也会发生类似的情况。它是否在每个类中创建一个指向每个 Vtable 的新指针?如果不是,当派生类的新实例被创建并分配给 Base PTR 时,它如何访问虚函数?
【问题讨论】:
对于每个具有虚函数的类,都会创建一个 vtable。然后,当使用构造函数创建具有可行性的类的对象时,构造函数将适当的 vtable 复制到对象中。因此,每个对象都有一个指向其 vtable 的指针(或者在多重继承的情况下,必要时,一个指向其每个 vtable 的 Orr。)。编译器知道vtable在对象中的什么位置,所以当它需要调用虚方法时,它会输出字节码来阻止vtable,查找合适的方法,然后跳转到它的地址。
在单继承的简单情况下,子类从父类的 vtable 副本开始,然后为子类中覆盖父类方法的每个虚拟方法获取一个覆盖条目。 (并且它还为子 clad 中的每个虚拟函数获取一个新条目,该条目 not 覆盖了父类方法)
【讨论】:
每次你创建一个包含虚函数的类,或者你 派生自包含虚函数的类,编译器 为该类创建一个唯一的 VTABLE。
如果你 不要覆盖在基类中声明为虚拟的函数, 编译器使用基类版本的地址 派生类。
然后它将 VPTR 放入 班上。使用 simple 时,每个对象只有一个 VPTR 继承。 VPTR 必须初始化为指向 适当的 VTABLE 的起始地址。 (这发生在 构造函数。) 一旦 VPTR 被初始化为正确的 VTABLE,对象在 effect“知道”它是什么类型。但这种自知是毫无价值的 除非在调用虚函数时使用它。 当你通过基类地址调用虚函数时( 编译器没有所有信息的情况 必须执行早期绑定),就会发生一些特殊的事情。 而不是执行典型的函数调用,这只是一个 汇编语言 CALL 到特定地址,编译器 生成不同的代码来执行函数调用。
【讨论】:
每当程序编译时,都会为每个类创建虚拟表,这清楚地表明虚拟表是基于每个类创建的。 在运行时,当创建对象时,编译器将 vptr 分配给对象,该对象指向特定类对象的虚拟表。 简而言之,vptr 是基于每个对象创建的。
【讨论】: