问题描述
如果我有这样的代码:
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,因为这两个函数都被声明为虚拟函数?
I get an error that says that I am trying to do an invalid conversion from int to void*. Why can't compiler figure out that he has to call B::f, since both functions are declared as virtual?
在阅读了 jalf 的回答后,我进一步减少了它.这个也不行.不是很直观.
After reading jalf's answer I went and reduced it even further. This one does not work as well. Not very intuitive.
struct A {
virtual void f(int) {}
};
struct B : public A {
void f(void*) {}
};
int main() {
B b;
b.f(1);
return 0;
}
推荐答案
简短的回答是因为这就是 C++ 中重载解析的工作方式".
The short answer is "because that's how overload resolution works in C++".
编译器在 C 类中搜索函数 F,如果找到,它会停止搜索,并尝试从中挑选一个候选函数.如果在派生类中没有找到匹配的函数,它只会在基类内部查找.
The compiler searches for functions F inside the C class, and if it finds any, it stops the search, and tries to pick a candidate among those. It only looks inside base classes if no matching functions were found in the derived class.
但是,您可以将基类函数显式引入派生类的命名空间:
However, you can explicitly introduce the base class functions into the derived class' namespace:
struct C : public B {
void f(void*) {}
using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};
这篇关于C++成员函数虚覆盖和同时重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!