Consider this demo program:
#include <stdio.h>
class Base
{
public:
virtual int f(int) =0;
virtual int f(){ return f(0); }
virtual ~Base(){ }
};
class Derived : public Base
{
public:
int f(int i)
{
return (10 + i);
}
};
int main(void)
{
Derived obj;
printf("%d\n", obj.f(1)); // This works, and returns 11
printf("%d\n", obj.f()); // Adding this line gives me the error listed below
}
Which gives me the following compilation error:
virtualfunc.cpp: In function ‘int main()’:
virtualfunc.cpp:25:26: error: no matching function for call to ‘Derived::f()’
virtualfunc.cpp:15:9: note: candidate is: virtual int Derived::f(int)
My hope was that a call to obj.f()
would result in a call to Base::obj.f()
since the derived class doesn't define it, which would then result in a call to Derived::obj.f(0)
per the definition in class Base.
What am I doing wrong here? Is there a way to accomplish this? Specifically, I'd like the call to obj.f()
to return 10.
(Also please note that I realize I could use a default argument to solve this, but this code is simply a concise example of my issue, so please don't tell me to use default arguments.)
Thanks.
The issue you're running into is orthogonal to pure virtual functions and has to do with how C++ does name resolution in class hierarchies.
When you write
C++ tries to look for a function named
f
so it knows what to call. Sinceobj
is of typeDerived
, it starts inside ofDerived
and looks for a function calledf
. It ends up findingDerived::f(int)
, and even though this function takes an argument, C++ thinks this is the method you're trying to call and thus stops looking. The compiler then notices that you're trying to invoke it with no parameters, giving you the error about the function call.To fix this, you need to tell the C++ compiler that it also needs to try looking for the function
Base::f()
, which is contained in the base class. To do this, you can change your definition ofDerived
as follows:This line
using Base::f
tells C++ that it should treat functions inBase
namedf
as though they are part ofDerived
. That way, when the compiler tries looking up a function namedf
, it finds bothDerived::f(int)
andBase::f()
. The call will then succeed because the compiler can figure out that you're trying to callBase::f()
with the code that you've listed.Hope this helps!
The reason is, that the defined
f
(inDerived
)hides
thef
functions from theBase
class. The solution is to addusing
. Like this:The definition of
f(int)
in the derived class hides the name ofBase::f
which you didn't override. All you need to do is to unhide this by writingusing Base::f;
in the derived class: