Виртуальная переопределения и перегрузка элемента С++ одновременно
Если у меня есть такой код:
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;
}
Ответы
Ответ 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
Ну, я думаю, прежде всего, вы не понимали, что такое виртуальный механизм или полиморфизм. Когда полиморфизм достигается только с помощью указателей объектов. Я думаю, что вы новичок в С++. Без использования указателей объектов нет смысла полиморфизма или виртуального ключевого слова использовать указатель базового класса и присваивать ему требуемые объекты производного класса. Затем вызовите и попробуйте.