Подтвердить что ты не робот

Виртуальная переопределения и перегрузка элемента С++ одновременно

Если у меня есть такой код:

struct A {
  virtual void f(int) {}
  virtual void f(void*) {}
};

struct B : public A {
  void f(int) {}
};

struct C : public B {
  void f(void*) {}
};


int main() {
  C c;
  c.f(1);

  return 0;
}

Я получаю сообщение об ошибке, которое говорит, что я пытаюсь сделать неверное преобразование из int в void *. Почему компилятор не может понять, что он должен вызывать B:: f, поскольку обе функции объявлены как виртуальные?


После прочтения jalf ответа я пошел и уменьшил его еще больше. Это тоже не работает. Не очень интуитивно.

struct A {
  virtual void f(int) {}
};

struct B : public A {
  void f(void*) {}
};


int main() {
  B b;
  b.f(1);

  return 0;
}
4b9b3361

Ответ 1

Короткий ответ - "потому что это то, как работает разрешение перегрузки на С++".

Компилятор ищет функции F внутри класса C, и если он находит что-либо, он останавливает поиск и пытается выбрать кандидата среди них. Он выглядит только внутри базовых классов, если в производном классе не найдено соответствующих функций.

Однако вы можете явно ввести функции базового класса в пространство имен производного класса:

struct C : public B {
  void f(void*) {}
  using B::f; // Add B f function to C namespace, allowing it to participate in overload resolution
};

Ответ 2

Или вы можете это сделать:

void main()
{
    A *a = new C();
    a->f(1);  //This will call f(int) from B(Polymorphism)
}

Ответ 3

Ну, я думаю, прежде всего, вы не понимали, что такое виртуальный механизм или полиморфизм. Когда полиморфизм достигается только с помощью указателей объектов. Я думаю, что вы новичок в С++. Без использования указателей объектов нет смысла полиморфизма или виртуального ключевого слова использовать указатель базового класса и присваивать ему требуемые объекты производного класса. Затем вызовите и попробуйте.