Полиморфизм, вызывающий функцию из базового класса - PullRequest
1 голос
/ 27 мая 2020

Итак, у меня есть эти классы:

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, как он может вызывать правильную функцию, vtable внутри test указывает на функцию базового класса getType() из-за типа test, поэтому как он может узнать, что это Derived::getType(), а не Base::getType(). Другими словами, что моя программа делает во время выполнения, когда видит это объявление test->getType()?

Заранее спасибо.

1 Ответ

2 голосов
/ 27 мая 2020

Когда вы делаете Base* test = new Derived():

Указатель V-таблицы объекта test устанавливается так, чтобы указывать на V-таблицу класса Derived.

Обратите внимание, что когда объект создается - через new Derived() - вы явно вызываете функцию (конструктор) класса Derived, а не класса Base.

И когда эта функция вызывается, она устанавливает v -табличный указатель нового объекта, указывающий на V-таблицу класса Derived, а не на класс Base.

AFAIK, фактические V-таблицы (обоих классов) генерируются компоновщик, прошедший компиляцию.

Дополнительно:

Программе не нужно «знать», что это функция virtual.

В случае при вызове невиртуальной функции компилятор добавляет инструкцию JUMP к постоянному адресу (т. е. адресу невиртуальной функции, который разрешается во время компиляции).

В случае вызова виртуальной функции , компилятор добавляет инструкцию JUMP к адресу, хранящемуся в (указанном) переменной, значение которой разрешается только во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...