问题
I have a base class with two overloaded functions f(void)
and f(int)
. The class Derived
implements f(int)
by calling f(void)
. Derived2
implements f(void)
only.
The compiler rejects the implementation Derived::f(int)
because it wants to call f(int)
but I provided no arguments because I want to call f(void)
. Why does the compiler reject it? Why does adding the line virtual int f(void) = 0;
fix my problem?
class Base
{
public:
explicit Base(void) {}
virtual ~Base(void) {}
virtual int f(void) = 0;
virtual int f(int i) = 0;
};
class Derived : public Base
{
public:
// provide implementation for f(int) which uses f(void). Does not compile.
virtual int f(int i) {puts("Derived::f(int)"); return f();}
// code only compiles by adding the following line.
virtual int f(void) = 0;
};
class Derived2 : public Derived
{
public:
// overwrite only f(void). f(int) is implemented by Derived.
virtual int f(void) {puts("Derived2::f(void)"); return 4;}
};
int main(void)
{
Base * p = new Derived2();
int i0 = p->f(); // outputs Derived2::f(void) and returns 4
int i1 = p->f(1); // outputs "Derived::f(int) Derived2::f(void)" and return 4
delete p;
return 0;
}
回答1:
Derived::f
hides Base::f
s. Given return f();
in the body of Derived::f(int)
, the name f
is found in the scope of Derived
, then name lookup stops. The names in Base
won't be found and participate in overload resolution.
name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
You can add using Base::f;
to introduce the name from Base
into the scope of Derived
.
class Derived : public Base
{
public:
using Base::f;
// provide implementation for f(int) which uses f(void).
virtual int f(int i) {puts("Derived::f(int)"); return f();}
};
来源:https://stackoverflow.com/questions/65018186/why-do-i-need-to-redeclare-overloaded-virtual-functions