0

Possible Duplicates:
C++ method only visible when object cast to base class?!
Why does an overridden function in the derived class hide other overloads of the base class?

#include <iostream>

using namespace std;

class A
{
public:
    virtual void foo(void) const { cout << "A::foo(void)" << endl; }
    virtual void foo(int i) const { cout << i << endl; }
    virtual ~A() {}
};

class B : public A
{
public:
    void foo(int i) const { this->foo(); cout << i << endl; }
};

class C : public B
{
public:
    void foo(void) const { cout << "C::foo(void)" << endl; }
};


int main(int argc, char ** argv)
{
    C test;

    test.foo(45);

    return 0;
}

The above code does not compile with:

$>g++ test.cpp -o test.exe
test.cpp: In member function 'virtual void B::foo(int) const':
test.cpp:17: error: no matching function for call to 'B::foo() const'
test.cpp:17: note: candidates are: virtual void B::foo(int) const
test.cpp: In function 'int main(int, char**)':
test.cpp:31: error: no matching function for call to 'C::foo(int)'
test.cpp:23: note: candidates are: virtual void C::foo() const

It compiles if method "foo(void)" is changed to "goo(void)". Why is this so? Is it possible to compile the code without changing the method name of "foo(void)"?

Thanks.

Community
  • 1
  • 1
devil
  • 1,829
  • 16
  • 23
  • 1
    Duplicate many times over, here's a few: http://stackoverflow.com/questions/2068088/c-method-only-visible-when-object-cast-to-base-class http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the http://stackoverflow.com/questions/888235/overriding-a-bases-overloaded-function-in-c – GManNickG Apr 22 '10 at 05:13
  • Also, the last duplicate got deleted for some reason. Don't delete duplicates, they give more keywords to search for when looking for pre-existing questions :/ – GManNickG Apr 22 '10 at 05:15
  • I didn't know the right keywords to search for. Inserting "using A::foo;" into class B and "using B::foo;" into class C solved the problem. The 2nd link had the best explanation on the name hiding. Thanks. – devil Apr 22 '10 at 05:24
  • 1
    No problem, searching can be tough. :) – GManNickG Apr 22 '10 at 05:28

2 Answers2

0

foo goo void int


I may be wrong but this might just be the problem:

Shadowing is based solely on name, not at all on the types of the parameters.The compiler observes that there is a function in derieved-class that hasthe correct name, and it stops looking. Having chosen a context, it looks for an applicable overload in derieved-class, and doesn't find one, so reports an error.

More details here
C++ method only visible when object cast to base class?


Class C has a foo(void)

In main() using:

test.foo(45);

you are passing int to foo function even though it is foo(void)
hence the errors:

test.cpp: In function 'int main(int, char**)':  
test.cpp:31: error: nomatching function for call to'C::foo(int)'

I hope i am making sense.
Is this it?? Comment anyone??...

Community
  • 1
  • 1
TheCodeArtist
  • 21,479
  • 4
  • 69
  • 130
  • 1
    No it is not. See the comments to the question for the right answer. – Draco Ater Apr 22 '10 at 05:30
  • Actually, I think the problem was more to do with "this->foo()" in line 17. i.e., if you change foo(void) to goo(void), line 31 is not a problem. – devil Apr 22 '10 at 05:33
0

The problem is, that inheritance is not carried over different namespaces. So to make it compile, you have to tell the compiler with the using directive:

class B : public A
{
public:
    using A::foo;
    void foo(int i) const { this->foo(); cout << i << endl; }
};

class C : public A
{
public:
    using B::foo;
    void foo(void) const { cout << "C::foo(void)" << endl; }
};
Michael Ulm
  • 802
  • 1
  • 7
  • 11
  • Should it be overloading instead of inheritance? – devil Apr 22 '10 at 05:39
  • @devil: Depends on what you're doing, though regardless those concepts aren't really related. – GManNickG Apr 22 '10 at 05:46
  • @Gman: The compile error does not happen solely with inheritance. E.g. if foo(void) is changed to goo(void) then there's only inheritance. It happens when inheritance is used in conjunction with overloading the foo method name. Although the concepts are unrelated, it seems that they are related in the language implementation as the overloaded functions are not inherited by default if any one of them is overridden by a subclass. – devil Apr 22 '10 at 06:41
  • @devil: more precisely, the lookup rules will stop looking up the hierarchy when they encounter the first identifier that matches the one that is beeing looked up. You can call the hidden method from the derived object: `myderived.base::foo()`, and the method is available for the derived type, but you must hint the compiler, as it will not be found with the regular lookup rules. – David Rodríguez - dribeas Apr 22 '10 at 07:47