C ++ полиморфный вызов без явного указателя - PullRequest
4 голосов
/ 06 мая 2011

Если у меня есть базовый класс:

struct Base
{
  void foo()
  {
    bar();
  }

  virtual void bar() 
  {
  }
};

И производный класс:

struct Derived : public Base
{
  void bar()
  {
    cerr << "Derived here\n";
  } 
};

Бывает так, что когда пишешь этот код:

Derived d;
d.foo();

Я увижу печать «Получено здесь» - так как Derived::bar был вызван. Но я не звонил через указатель на базу, а здесь работает полиморфизм. Зачем? Это потому, что вызов bar в Base::foo неявно фактически this->bar() и bar находится в vtable класса?

Ответы [ 4 ]

4 голосов
/ 06 мая 2011

Ваше предположение точно верно (хотя имейте в виду, что стандарт C ++ ничего не говорит о vtables).

1 голос
/ 06 мая 2011

Это потому, что вызов bar в Base :: foo неявно фактически связан с this-> bar (), а bar находится в vtable класса?

Вызов d.foo() фактически выполняет (&d)->foo(), поэтому foo() получает указатель this, ищет виртуальную таблицу и находит правильную реализацию bar().

Другими словами, для foo() не имеет значения, был ли он вызван через указатель или нет. Он всегда получает указатель this и работает одинаково независимо.

0 голосов
/ 06 мая 2011

1) почему вы определяете методы в структурах?

2) да, полиморфизм - это то, что заставляет вас называть Derived::foo() вместо Base::foo(), потому что вы объявили его виртуальным. Действительно, это позволило коду найти правильный метод в виртуальной таблице класса (или любой структуре таблицы указателей, которую компилятор создает для вас, чтобы отслеживать полиморфные методы.)

0 голосов
/ 06 мая 2011

Вы были наполовину правы.Это не явный указатель, но он ищет в vtable первую запись для этой функции.Поскольку производный класс предоставил новую запись для этой функции, вы вызываете производную функцию.Полиморфизм работает независимо от указателей - просто во всех примерах используются указатели, чтобы показать, насколько легко отделить использование полиморфизма

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