简体   繁体   中英

C++ Compiler (cl) does not see parent virtual method with same child method name

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?

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;
};

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:

  • in Child *c = new Child(); c->G("test"); 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.
  • The compiler, when exploring the scope of 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.
  • The compiler thus is happy having found 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM