【问题标题】:How Vtable of Virtual functions work虚函数的 Vtable 是如何工作的
【发布时间】:2012-04-21 08:19:17
【问题描述】:

我对Virtual Table有一点疑问,每当编译器遇到类中的虚函数时,它都会创建Vtable并将虚函数地址放置在那里。对于继承的其他类,它也会发生类似的情况。它是否在每个类中创建一个指向每个 Vtable 的新指针?如果不是,当派生类的新实例被创建并分配给 Base PTR 时,它如何访问虚函数?

【问题讨论】:

标签: c++ virtual vtable


【解决方案1】:

对于每个具有虚函数的类,都会创建一个 vtable。然后,当使用构造函数创建具有可行性的类的对象时,构造函数将适当的 vtable 复制到对象中。因此,每个对象都有一个指向其 vtable 的指针(或者在多重继承的情况下,必要时,一个指向其每个 vtable 的 Orr。)。编译器知道vtable在对象中的什么位置,所以当它需要调用虚方法时,它会输出字节码来阻止vtable,查找合适的方法,然后跳转到它的地址。

在单继承的简单情况下,子类从父类的 vtable 副本开始,然后为子类中覆盖父类方法的每个虚拟方法获取一个覆盖条目。 (并且它还为子 clad 中的每个虚拟函数获取一个新条目,该条目 not 覆盖了父类方法)

【讨论】:

    【解决方案2】:

    每次你创建一个包含虚函数的类,或者你 派生自包含虚函数的类,编译器 为该类创建一个唯一的 VTABLE。

    如果你 不要覆盖在基类中声明为虚拟的函数, 编译器使用基类版本的地址 派生类。

    然后它将 VPTR 放入 班上。使用 simple 时,每个对象只有一个 VPTR 继承。 VPTR 必须初始化为指向 适当的 VTABLE 的起始地址。 (这发生在 构造函数。) 一旦 VPTR 被初始化为正确的 VTABLE,对象在 effect“知道”它是什么类型。但这种自知是毫无价值的 除非在调用虚函数时使用它。 当你通过基类地址调用虚函数时( 编译器没有所有信息的情况 必须执行早期绑定),就会发生一些特殊的事情。 而不是执行典型的函数调用,这只是一个 汇编语言 CALL 到特定地址,编译器 生成不同的代码来执行函数调用。

    【讨论】:

    • 所以,你的意思是说喜欢。只有一个 VPTR 它在创建对象期间而不是在分配权期间指向特定的表。但它始终存在于基类中。
    • 正如我所说,编译器为一个类及其派生类创建了一个唯一的 VTABLE。
    • VTABLE 的 VPTR 怎么样?实例化派生类并分配给基 ptr 时它是如何工作的?
    • 当你通过基类指针进行虚函数调用时(即当你进行多态调用时),编译器悄悄地插入代码来获取 VPTR 并在 VTABLE 中查找函数地址,因此调用正确的函数并导致后期绑定发生。
    【解决方案3】:

    每当程序编译时,都会为每个类创建虚拟表,这清楚地表明虚拟表是基于每个类创建的。 在运行时,当创建对象时,编译器将 vptr 分配给对象,该对象指向特定类对象的虚拟表。 简而言之,vptr 是基于每个对象创建的。

    【讨论】:

      猜你喜欢
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      • 2017-05-31
      相关资源
      最近更新 更多