I have a baseclass that has two functions of same name but with different signatures in a 2-level inheritance.
struct A {
virtual void f(int) { }
virtual void f(int, int) { };
virtual void f1(int) { }
};
struct B: public A { };
struct C: public开发者_高级运维 B {
void f(int, int) { }
void f1(int) { }
};
int main() {
C obj;
obj.f1(0);
obj.f(0,0);
obj.f(0); // (1) cannot be found
obj.B::f(0); // (2) works
}
I would have expected my compiler (gcc-4.3.2) to find the correct definition at (1)
, but I get
g++ main.cpp -o main
main.cpp: In function 'int main()':
main.cpp:20: error: no matching function for call to 'C::f(int)'
main.cpp:10: note: candidates are: virtual void C::f(int, int)
distcc[2200] ERROR: compile main.cpp on localhost failed
make: *** [main] Error 1
(2)
on the other hand works.
What do I need to fix to make (1)
work in general?
Write using A::f
inside the definition of C.
You are a victim of name hiding! void C::f(int, int)
hides void A::f(int)
, just because.
The C++ name lookup rules have it so that if a name is redefined in one scope, all overloads of that name are hidden.
But you can use using
to help. Like this:
class A {
public:
int f(int x) { cout << "A::f 1\n"; }
int f(int x, int y) { cout << "A::f 2\n"; }
};
class B : public A {
public:
using A::f;
int f(int x) { cout << "B::f 1\n"; }
};
int main()
{
B b;
b.f(27, 34);
return 0;
}
Output is:
A::f 2
The short answer to "why" is "because that's how overloading works." You are hiding the f(int)
overload in C. The longer answer is much longer.
You can un-hide it by doing this:
struct C: public B {
using A::f;
void f(int, int) { }
void f1(int) { }
};
精彩评论