Как переназначение указателей влияет на полиморфизм - PullRequest
1 голос
/ 04 апреля 2020

Вот то, что мне интересно. Есть 2 указателя, соответствующих 2 экземплярам класса. Код выводит 6 строк (согласно комментариям). Первые 4 имеют смысл для меня, но я не понимаю последних 2. Я ожидал, что строки 5 и 6 будут равны линиям 3 и 4, поскольку pb и pd теперь обе указывают на один и тот же объект. Пожалуйста, помогите мне понять.

#include <iostream>

using namespace std;

class B {
public:
  virtual void run1(){cout << "Base" << endl;}
  void run2(){cout << "Base" << endl;}
};

class D: public B {
public:
  virtual void run1(){cout << "Derived" << endl;}
  void run2(){cout << "Derived" << endl;}
};

int main(int argc, char* argv[])
{
  B b, *pb;
  D d, *pd;

  pb = &b;
  pb->run1(); //Base
  pb->run2(); //Base

  pd = &d;
  pd->run1(); //Derived
  pd->run2(); //Derived

  pb = &d;
  pb->run1(); //Derived (why ?)
  pb->run2(); //Base    (why ?)
}

1 Ответ

1 голос
/ 04 апреля 2020

Функция run1 является виртуальной функцией, в то время как функция run2 не является виртуальной функцией.

Виртуальные функции вызываются в соответствии с типом динамического c используемого указателя, в то время как не являются виртуальными. Функции вызываются в соответствии с типом используемого указателя stati c.

Тип указателя * stati c pb равен B *.

  B b, *pb;

После этого присваивание

pb = &b;

тип указателя динамического c также B *. Поэтому вызывается виртуальная функция, определенная в классе B.

После этого присваивания

pb = &d;

тип указателя динамического c pb изменен с B * на D *.

Таким образом, в этом операторе

pb->run1(); //Derived (why ?)

вызывается виртуальная функция в соответствии с типом указателя динамического c. В то время как в этом операторе

pb->run2(); //Base    (why ?)

вызывается не виртуальная функция в соответствии с типом указателя stati c.

Это указатель на таблицу указателей виртуальных функций ищется в объекте, на который указывает используемый указатель.

Эта функция определяет поведение полиморфа c.

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