Connecting Tech Pros Worldwide Forums | Help | Site Map

Overriding virtual functions problem

AGoTH
Guest
 
Posts: n/a
#1: Jul 19 '05
class A {
public:
virtual void foo(int b) {}
virtual void foo(char* b) {}
};

class B : public A{
virtual void foo(int b) {}
};


void
foo()
{
B* b;
b->foo("tgre");
}

this code does not compile, neither in Visual C++ nor in Codewarrior.
Does someone know why ?

Aymeric Bard.

Jakob Bieling
Guest
 
Posts: n/a
#2: Jul 19 '05

re: Overriding virtual functions problem


"AGoTH" <agoth@virtools.com> wrote in message
news:26b89bd2.0308080425.7666bd56@posting.google.c om...[color=blue]
> class A {
> public:
> virtual void foo(int b) {}
> virtual void foo(char* b) {}
> };
>
> class B : public A{
> virtual void foo(int b) {}
> };
>
>
> void
> foo()
> {
> B* b;
> b->foo("tgre");
> }
>
> this code does not compile, neither in Visual C++ nor in Codewarrior.
> Does someone know why ?[/color]


The 'foo(int)' in B hides 'foo(char*)' of A and overloads 'foo(int)'
Define an overload for 'foo(char*)' in B, where you just forward the call to
'A::foo(int)'.

hth
--
jb

(replace y with x if you want to reply by e-mail)


Karl Heinz Buchegger
Guest
 
Posts: n/a
#3: Jul 19 '05

re: Overriding virtual functions problem




Jakob Bieling wrote:[color=blue]
>
> "AGoTH" <agoth@virtools.com> wrote in message
> news:26b89bd2.0308080425.7666bd56@posting.google.c om...[color=green]
> > class A {
> > public:
> > virtual void foo(int b) {}
> > virtual void foo(char* b) {}
> > };
> >
> > class B : public A{
> > virtual void foo(int b) {}
> > };
> >
> >
> > void
> > foo()
> > {
> > B* b;
> > b->foo("tgre");
> > }
> >
> > this code does not compile, neither in Visual C++ nor in Codewarrior.
> > Does someone know why ?[/color]
>
> The 'foo(int)' in B hides 'foo(char*)' of A and overloads 'foo(int)'
> Define an overload for 'foo(char*)' in B, where you just forward the call to
> 'A::foo(int)'.[/color]

or add a using directive to class B

class B : public A
{
using A::foo;

--
Karl Heinz Buchegger
kbuchegg@gascad.at
Karl G. Merkley
Guest
 
Posts: n/a
#4: Jul 19 '05

re: Overriding virtual functions problem


Jakob Bieling wrote:[color=blue]
> "Karl Heinz Buchegger" <kbuchegg@gascad.at> wrote in message
> news:3F339B92.FF354750@gascad.at...
>[color=green]
>>
>>Jakob Bieling wrote:
>>[color=darkred]
>>>"AGoTH" <agoth@virtools.com> wrote in message
>>>news:26b89bd2.0308080425.7666bd56@posting.googl e.com...
>>>
>>>>class A {
>>>>public:
>>>>virtual void foo(int b) {}
>>>>virtual void foo(char* b) {}
>>>>};
>>>>
>>>>class B : public A{
>>>>virtual void foo(int b) {}
>>>>};
>>>>
>>>>
>>>>void
>>>>foo()
>>>>{
>>>>B* b;
>>>>b->foo("tgre");
>>>>}
>>>>
>>>>this code does not compile, neither in Visual C++ nor in Codewarrior.
>>>>Does someone know why ?
>>>
>>> The 'foo(int)' in B hides 'foo(char*)' of A and overloads 'foo(int)'
>>>Define an overload for 'foo(char*)' in B, where you just forward the[/color]
>>[/color]
> call to
>[color=green][color=darkred]
>>>'A::foo(int)'.[/color]
>>
>>or add a using directive to class B
>>
>>class B : public A
>>{
>> using A::foo;[/color]
>
>
>
> This one is actually much nicer! Thanks for the hint!
>
>[/color]
I was just about to ask this same question! I'm still not completely clear on
why 'foo(int)' in B hides 'foo(char*)' in A. I would have thought that the name
mangling would have created completely different symbols for 'foo(int)' and
'foo(char*)' and thus 'foo(char*)' would not be hidden.

Karl


Kevin Goodsell
Guest
 
Posts: n/a
#5: Jul 19 '05

re: Overriding virtual functions problem


Jakob Bieling wrote:
[color=blue]
> "AGoTH" <agoth@virtools.com> wrote in message
> news:26b89bd2.0308080425.7666bd56@posting.google.c om...
>[color=green]
>>class A {
>>public:
>>virtual void foo(int b) {}
>>virtual void foo(char* b) {}
>>};
>>
>>class B : public A{
>>virtual void foo(int b) {}
>>};
>>
>>
>>void
>>foo()
>>{
>>B* b;
>>b->foo("tgre");
>>}
>>
>>this code does not compile, neither in Visual C++ nor in Codewarrior.
>>Does someone know why ?[/color]
>
>
>
> The 'foo(int)' in B hides 'foo(char*)' of A and overloads 'foo(int)'
> Define an overload for 'foo(char*)' in B, where you just forward the call to
> 'A::foo(int)'.[/color]

I think you meant to say:

The 'foo(int)' in B hides 'foo(char*)' of A and _overrides_ 'foo(int)'.
Define an overload for 'foo(char*)' in B, where you just forward the
call to _'A::foo(char*)'_.

Of course, a using declaration is an easier solution.

This is a pretty common question, and the basic answer is "function
overload resolution does not cross inheritance boundaries."

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jakob Bieling
Guest
 
Posts: n/a
#6: Jul 19 '05

re: Overriding virtual functions problem


"Kevin Goodsell" <usenet1.spamfree.fusion@neverbox.com> wrote in message
news:3f33f6bd@shknews01...[color=blue]
> Jakob Bieling wrote:
>[color=green]
> > "AGoTH" <agoth@virtools.com> wrote in message
> > news:26b89bd2.0308080425.7666bd56@posting.google.c om...
> >[color=darkred]
> >>class A {
> >>public:
> >>virtual void foo(int b) {}
> >>virtual void foo(char* b) {}
> >>};
> >>
> >>class B : public A{
> >>virtual void foo(int b) {}
> >>};
> >>
> >>
> >>void
> >>foo()
> >>{
> >>B* b;
> >>b->foo("tgre");
> >>}
> >>
> >>this code does not compile, neither in Visual C++ nor in Codewarrior.
> >>Does someone know why ?[/color]
> >
> >
> >
> > The 'foo(int)' in B hides 'foo(char*)' of A and overloads 'foo(int)'
> > Define an overload for 'foo(char*)' in B, where you just forward the[/color][/color]
call to[color=blue][color=green]
> > 'A::foo(int)'.[/color]
>
> I think you meant to say:
>
> The 'foo(int)' in B hides 'foo(char*)' of A and _overrides_ 'foo(int)'.
> Define an overload for 'foo(char*)' in B, where you just forward the
> call to _'A::foo(char*)'_.[/color]

Uh yes, got confused by all the overriding and hiding and overloading ;)

Thanks for the correction!
--
jb

(replace y with x if you want to reply by e-mail)


Victor Bazarov
Guest
 
Posts: n/a
#7: Jul 19 '05

re: Overriding virtual functions problem


"NeilF" <neilQdQferguson@hotmail.com> wrote...[color=blue]
> [...]
> Unless it's explained in the FAQ, perhaps you could take the time to[/color]
explain[color=blue]
> why hiding related member functions is useful. Perhaps it's something to[/color]
do[color=blue]
> with avoiding program misbehavior caused by implicit parameter casting?[/color]

I am fairly sure that the rationale behind name hiding has been already
given in one form or another, and if you look for it, you'll find it.
No, I don't have any links off the top of my head. And it's been some
time since I opened D&E ("Design and Evolution of C++" by Stroustrup)
last time, I just don't remember if there is some description there.

Name hiding is fundamental and is not C++ specific. In C, if you declare
a variable in a block, it would hide another variable with the same name
in the enclosing block. It's been like this for ages.

I believe that when the time came to define the relationship of derived
classes' scopes, Bjarne had only two possible outcomes: either make class
scopes follow the normal nested scopes line or make them an exception.
Perhaps making them an exception promised more unnecessary complexity and
would be more difficult to explain and justify. I don't know for sure.

Try asking in comp.std.c++. Most of Standard Committee people frequent
that newsgroup, many must remember why name hiding was extended onto class
members (or have some links handy). It's actually much better place to
ask the "why" questions than comp.lang.c++. Here we mostly talk "how".

Victor


Victor Bazarov
Guest
 
Posts: n/a
#8: Jul 19 '05

re: Overriding virtual functions problem


"NeilF" <neilQdQferguson@hotmail.com> wrote...[color=blue]
> [...]
> Unless it's explained in the FAQ, perhaps you could take the time to[/color]
explain[color=blue]
> why hiding related member functions is useful. Perhaps it's something to[/color]
do[color=blue]
> with avoiding program misbehavior caused by implicit parameter casting?[/color]

I am fairly sure that the rationale behind name hiding has been already
given in one form or another, and if you look for it, you'll find it.
No, I don't have any links off the top of my head. And it's been some
time since I opened D&E ("Design and Evolution of C++" by Stroustrup)
last time, I just don't remember if there is some description there.

Name hiding is fundamental and is not C++ specific. In C, if you declare
a variable in a block, it would hide another variable with the same name
in the enclosing block. It's been like this for ages.

I believe that when the time came to define the relationship of derived
classes' scopes, Bjarne had only two possible outcomes: either make class
scopes follow the normal nested scopes line or make them an exception.
Perhaps making them an exception promised more unnecessary complexity and
would be more difficult to explain and justify. I don't know for sure.

Try asking in comp.std.c++. Most of Standard Committee people frequent
that newsgroup, many must remember why name hiding was extended onto class
members (or have some links handy). It's actually much better place to
ask the "why" questions than comp.lang.c++. Here we mostly talk "how".

Victor


Jerry Coffin
Guest
 
Posts: n/a
#9: Jul 19 '05

re: Overriding virtual functions problem


In article <BQeZa.106393$Ho3.13941@sccrnsc03>, v.Abazarov@attAbi.com
says...

[ ... ]
[color=blue]
> I believe that when the time came to define the relationship of derived
> classes' scopes, Bjarne had only two possible outcomes: either make class
> scopes follow the normal nested scopes line or make them an exception.
> Perhaps making them an exception promised more unnecessary complexity and
> would be more difficult to explain and justify. I don't know for sure.[/color]

I the D&E, Bjarne also mentions that if you looked in the base class, it
could rather unexpectedly change how programs worked. Just for example,
assume a base class has f(long) and a derived class has f(long). If you
call f(1), it basically invokes derived::f(1L) (i.e. invokes the derived
version of f, converting the argument to a long in the process.

Now, if it looked in the base class as well, then adding f(int) to the
base would mean that the client code would now invoke base::f(1). A
seemingly rather innocent change in the base class might make wholesale
changes in code that doesn't use the base class directly at all.

In particular, while the current situation causes something new users
often find unexpected, it's (generally) something that becomes obvious
when you first write the client code -- typically, it won't compile at
all, because the code attempts to call a function that's no longer
visible.

The alternative is rather the opposite: it can silently change behavior
long after code is written, and many compilers would probably let you do
it without so much as a peep of warning either (though if it's a major
change in behavior, the design is probably suspect).

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jerry Coffin
Guest
 
Posts: n/a
#10: Jul 19 '05

re: Overriding virtual functions problem


In article <BQeZa.106393$Ho3.13941@sccrnsc03>, v.Abazarov@attAbi.com
says...

[ ... ]
[color=blue]
> I believe that when the time came to define the relationship of derived
> classes' scopes, Bjarne had only two possible outcomes: either make class
> scopes follow the normal nested scopes line or make them an exception.
> Perhaps making them an exception promised more unnecessary complexity and
> would be more difficult to explain and justify. I don't know for sure.[/color]

I the D&E, Bjarne also mentions that if you looked in the base class, it
could rather unexpectedly change how programs worked. Just for example,
assume a base class has f(long) and a derived class has f(long). If you
call f(1), it basically invokes derived::f(1L) (i.e. invokes the derived
version of f, converting the argument to a long in the process.

Now, if it looked in the base class as well, then adding f(int) to the
base would mean that the client code would now invoke base::f(1). A
seemingly rather innocent change in the base class might make wholesale
changes in code that doesn't use the base class directly at all.

In particular, while the current situation causes something new users
often find unexpected, it's (generally) something that becomes obvious
when you first write the client code -- typically, it won't compile at
all, because the code attempts to call a function that's no longer
visible.

The alternative is rather the opposite: it can silently change behavior
long after code is written, and many compilers would probably let you do
it without so much as a peep of warning either (though if it's a major
change in behavior, the design is probably suspect).

--
Later,
Jerry.

The universe is a figment of its own imagination.
Closed Thread