Reputation: 2617
I have a C++ code, using inheritance and function overriding at the same time, here is the code:
#include <iostream>
#include <string>
using namespace std;
class Parent
{
protected:
virtual void G() const = 0;
public:
virtual void G(const string& s) const final { G(); }
};
class Child : public Parent
{
protected:
virtual void G() const override { cout<<"Child G"; }
};
int main()
{
Child *c = new Child();
c->G("test");
return 0;
}
When compile, I got error: Child::G: function does not take 1 arguments
. But when I use Parent pointer like this:
Parent *c = new Child();
It works. Alternatively if I change public G
method's name, it works too.
What is wrong about using same name (G
) for both methods?
Upvotes: 1
Views: 68
Reputation: 7202
The fix for this is indeed to introduce the Parent
's method into the scope of the Child
class with a using
declaration, as @Jans kindly points out. As to why this is the case is simply a matter of how the compiler searches through scopes when searching for a method to match your function call. A break down of what's happening is as follows:
Child *c = new Child(); c->G("test");
, the compiler sees a call to some method G
on an object of type Child
. It then searches the scope of Child
to look for a match.Child
, sees only Child::G() const
. It does not see Parent::G(const std::string&) const
, which even though you want it to be included via inheritance, is in a different scope. In a sense, Child::G
is shadowing Parent::G
. Without a candidate match, the compiler would have kept searching into the Parent
scope.Child::G
. However, this is a function accepting no arguments, and you tried to call it with "test"
. The function call then fails because of a mismatch in the parameters.As stated, you need to bring Parent::G
into the same scope as Child::G
for overloading to happen as intended, with using Parent::G
inside the body of Child
.
Source: https://isocpp.org/wiki/faq/strange-inheritance#overload-derived
Upvotes: 1
Reputation: 11250
You need to introduce the parent member into the child with a using
declaration:
class Child : public Parent
{
protected:
virtual void G() const override { cout<<"Child G"; }
public:
using Parent::G;
};
Upvotes: 3