首页 > 解决方案 > 从基类调用函数的多态性

问题描述

所以我有这些课程:

class Base {
public:
   Base() {cout << "made a base" << endl;}
   virtual void getType() const { cout << "Im a base" << endl;
   virtual ~Base() {}
   //other members...
}

class Derived: public Base {
public:
    Derived() {cout << "made a derived" << endl;
    virtual void getType() const { cout << "Im a derived" << endl; }
    virtual ~Derived() {}
    //other memebrs...
}


int main() {

    Base* test = new Derived();
    test->getType();

    return 0;
}

输出:

made a base
made a derived
Im a derived

现在我知道输出是Im a derived由于多态性,但是我想知道它如何在内部与 Vftables 一起工作,它如何调用正确的函数,内部的 vtabletest指向 Base 类getType()函数,因为test它的类型知道它是Derived::getType()而不是Base::getType()。换句话说,当我的程序看到这个声明时,它在运行时会做什么test->getType()

提前致谢。

标签: c++polymorphism

解决方案


当你这样做Base* test = new Derived()

object 的 V-Table 指针test被设置为指向 class 的 V-Table Derived

请注意,当对象被创建时 - 通过new Derived()- 您显式调用了 class 的函数(构造函数)Derived而不是 class Base

当这个函数被调用时,它会将新对象的 v-table 指针设置为指向 class 的 V-TableDerived而不是 class 的Base

AFAIK,实际的 V 表(两个类的),是由链接器在编译后生成的。

补充:

程序不需要“知道”一个函数是virtual.

在非虚函数调用的情况下,编译器会在一个常量地址(即非虚函数的地址,在编译过程中可解析)中添加一条JUMP指令。

在虚函数调用的情况下,编译器将 JUMP 指令添加到存储在(指向)变量中的地址,该变量的值仅在运行时解析。


推荐阅读