Derived class losing base member function?

S

Steve Canfield

When compiling the following code:

class Base
{
...
virtual void Fn(int x);
virtual void Fn(Base x);
};

class Derived : public Base
{
...
virtual void Fn(Base x);
};

Derived d;
d.Fn(5);

I get the following error:
no matching function for call to `Derived::Fn(int)'
candidates are: void Derived::Fn(Base)

Shouldn't the compiler (g++) see the public function Base::Fn(int)?
The errors go away if I help the compiler out:
d.Base::Fn(5)
but I'm not sure why I need to do that.

-steve
 
M

Mike Wahler

Steve Canfield said:
When compiling the following code:

class Base
{
...
virtual void Fn(int x);
virtual void Fn(Base x);
};

class Derived : public Base
{
...
virtual void Fn(Base x);
};

Derived d;
d.Fn(5);

I get the following error:
no matching function for call to `Derived::Fn(int)'
candidates are: void Derived::Fn(Base)

Shouldn't the compiler (g++) see the public function Base::Fn(int)?
The errors go away if I help the compiler out:
d.Base::Fn(5)
but I'm not sure why I need to do that.

You didn't override 'Fn(int)' in the base class.
Since you're not making a polymorphic call (via a pointer
or reference to the base class), only class 'Derived's
member functions are candidates for name lookup.

A similar issue was just discussed a little while ago.
See the thread initiated by Kris Thielemans entitled
"calling virtual function that is hidden by inheritance".

You've already 'stumbled' upon the correct solution. :)

-Mike
 
J

Jonathan Mcdougall

When compiling the following code:
class Base
{
...
virtual void Fn(int x);
virtual void Fn(Base x);
};

class Derived : public Base
{
...
virtual void Fn(Base x);
};

Derived d;
d.Fn(5);

I get the following error:
no matching function for call to `Derived::Fn(int)'
candidates are: void Derived::Fn(Base)

Shouldn't the compiler (g++) see the public function Base::Fn(int)?

Nope. Adding a function to a derived class hides all the base's
member functions having the same name. You must bring them into
the derived's scope :

class Derived : public Base
{
using Base::Fn;

...
};

The errors go away if I help the compiler out:
d.Base::Fn(5)
but I'm not sure why I need to do that.

Because you are explicitly telling the compiler which function to use.


Jonathan
 
J

Jonathan Mcdougall

I get the following error:
Nope. Adding a function to a derived class hides all the base's
member functions having the same name. You must bring them into
the derived's scope :

Missed the virtual. See Mike's answer, I'm plain wrong.


Jonathan
 
M

Mike Wahler

Jonathan Mcdougall said:
Missed the virtual. See Mike's answer, I'm plain wrong.

Don't feel bad. I started writing a reply saying what you
did, but was lucky enough to catch myself before pressing
"send". :)

-Mike
 
T

tom_usenet

Missed the virtual. See Mike's answer, I'm plain wrong.

But you're right! The using declaration brings Base::Fn(int) into
derived member lookup scope, which is exactly what the OP wanted. The
virtual bit is irrelevent, since the OP still wants to call the most
overridden version of the function.

Why do you think you're wrong?

Tom
 
S

Steve Canfield

tom_usenet said:
But you're right! The using declaration brings Base::Fn(int) into
derived member lookup scope, which is exactly what the OP wanted. The
virtual bit is irrelevent, since the OP still wants to call the most
overridden version of the function.

Why do you think you're wrong?

Thanks Tom- adding the using declaration fixed the problem. Mike &
Jonathan- you guys didn't expect the using to work but it seems to do
exactly what I wanted. Is there something strange going on here?

-steve
 
J

jeffc

Steve Canfield said:
When compiling the following code:

class Base
{
...
virtual void Fn(int x);
virtual void Fn(Base x);
};

class Derived : public Base
{
...
virtual void Fn(Base x);
};

Derived d;
d.Fn(5);

I get the following error:
no matching function for call to `Derived::Fn(int)'
candidates are: void Derived::Fn(Base)

Shouldn't the compiler (g++) see the public function Base::Fn(int)?
The errors go away if I help the compiler out:
d.Base::Fn(5)
but I'm not sure why I need to do that.

Your "virtual" functions aren't really doing anything virtual because you're
not really using polymorphism. Try this
Base* d = new Derived;
d->Fn(5);
 
J

jeffc

Steve Canfield said:
Thanks Tom- adding the using declaration fixed the problem. Mike &
Jonathan- you guys didn't expect the using to work but it seems to do
exactly what I wanted. Is there something strange going on here?

They're both right. The way you have the code written, the virtual
declarators are useless. It would do the same thing if you took them out.
On the other hand, even with them out, and even with a Derived object
defined as you have defined it, the call you want is now not in scope. So I
don't think this is "exactly what the OP wanted" as tom said. I think you
intended it to work polymorphically, or else you wouldn't have used
"virtual", right? So there are really 2 issues here.
 
S

Steve Canfield

jeffc said:
Your "virtual" functions aren't really doing anything virtual because you're
not really using polymorphism. Try this
Base* d = new Derived;
d->Fn(5);

I understand in the chunk of code that I've posted, the virtual
keyword isn't doing anything. In other places I do work with base
class pointers, but I tried to keep the code to a minimum.

The using declaration that Jonathan suggested (then retracted) does
seem to work. Now I'm curious about why Jonathan retracted his
suggestion after he noticed the virtual keyword. What does that have
to do with anything?

-steve
 
T

tom_usenet

I understand in the chunk of code that I've posted, the virtual
keyword isn't doing anything. In other places I do work with base
class pointers, but I tried to keep the code to a minimum.

The using declaration that Jonathan suggested (then retracted) does
seem to work. Now I'm curious about why Jonathan retracted his
suggestion after he noticed the virtual keyword. What does that have
to do with anything?

Nothing - the using declaration will only effect name lookup of
derived members (for which you need a derived reference/object).
Virtual dispatch from a Base reference will be completely unaffected.

Tom
 
J

jeffc

Steve Canfield said:
I understand in the chunk of code that I've posted, the virtual
keyword isn't doing anything. In other places I do work with base
class pointers, but I tried to keep the code to a minimum.

The using declaration that Jonathan suggested (then retracted) does
seem to work. Now I'm curious about why Jonathan retracted his
suggestion after he noticed the virtual keyword. What does that have
to do with anything?

He was just a bit flummoxed by Mike's response at first. As I said, I think
there are really 2 issues here - both Jonathan and Mike were right. The
only question is which issue you were really interested in.
 
T

tom_usenet

I understand in the chunk of code that I've posted, the virtual
keyword isn't doing anything. In other places I do work with base
class pointers, but I tried to keep the code to a minimum.

The using declaration that Jonathan suggested (then retracted) does
seem to work. Now I'm curious about why Jonathan retracted his
suggestion after he noticed the virtual keyword. What does that have
to do with anything?

On a final note:

http://www.research.att.com/~bs/bs_faq2.html#overloadderived

Tom
 
S

Steve Canfield

Mike Wahler said:
You didn't override 'Fn(int)' in the base class.
Since you're not making a polymorphic call (via a pointer
or reference to the base class), only class 'Derived's
member functions are candidates for name lookup.

A similar issue was just discussed a little while ago.
See the thread initiated by Kris Thielemans entitled
"calling virtual function that is hidden by inheritance".

You've already 'stumbled' upon the correct solution. :)

But the solution I stumbled upon isn't really the one I wanted. I much
perfer adding a 'using' declaration. That's what I did and it seems to
work.

Thanks for your help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top