views:

156

answers:

3

This doesn't work:

class Foo
{
public:
    virtual int A(int);
    virtual int A(int,int);
};
class Bar : public Foo
{
public:
    virtual int A(int);
};

Bar b;
int main()
{
    b.A(0,0);
}

It seems that by overriding Foo::A(int) with Bar::A(int) I have somehow hidden Foo::A(int,int). If I add a Bar::A(int,int) things work.

Does anyone have a link to a good description of what's going on here?

+5  A: 

Essentially, name lookup happens before overload resolution so the function A in your derived class overrides the virtual function in the base class but hides all other functions with the same name in any base classes.

Possible solutions include adding a using Foo::A; directive into your derived class to make all the base class members called A visible in the derived class or using different names for functions with different signatures.

See here as well.

Charles Bailey
It's nice to get my suspicions confirmed. Do you know of a link to a full description of this corner of C++?
BCS
Name hiding is described in 3.3.7 [basic.scope.hiding] of the standard, name lookup is the whole of 3.4 [basic.lookup] and there's an entire chapter (13 [over]) on overloading and overload resolution. The basic rule for your situation is just as I've described, though.
Charles Bailey
+2  A: 

There's a discussion on there here: http://bojolais.livejournal.com/222428.html

The crux is: In C++, when you have a class with an overloaded method (member function, whatever you want to call it), and you then extend and override that method, you must override all of the overloaded method

A workaround is to change the call to:

b.Foo::A(0, 0);
nall
A: 

The easiest way of thinking about this is to remember that overloading always occurs WITHIN a single scope, while overriding appears between scopes. When figuring out which function to call, the compiler FIRST looks to find the closest scope that has the the name and then resolves overloading between definitions in that scope.

Chris Dodd