问题描述
如果我有这样的代码:
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 to 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.
但是,您可以将基类函数显式地引入到派生类的命名空间中: / p>
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 ++成员函数虚函数重载和重载同时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!