views:

235

answers:

2

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.

A: 

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
http://stackoverflow.com/questions/2068088/


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??...

CVS-2600Hertz
No it is not. See the comments to the question for the right answer.
Draco Ater
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
A: 

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
Should it be overloading instead of inheritance?
devil
@devil: Depends on what you're doing, though regardless those concepts aren't really related.
GMan
@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
@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