By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,241 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

Overriding virtual functions problem

P: n/a
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.
Jul 19 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
"AGoTH" <ag***@virtools.com> wrote in message
news:26**************************@posting.google.c om...
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 call to
'A::foo(int)'.

hth
--
jb

(replace y with x if you want to reply by e-mail)
Jul 19 '05 #2

P: n/a


Jakob Bieling wrote:

"AGoTH" <ag***@virtools.com> wrote in message
news:26**************************@posting.google.c om...
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 call to
'A::foo(int)'.


or add a using directive to class B

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

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #3

P: n/a
Jakob Bieling wrote:
"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...

Jakob Bieling wrote:
"AGoTH" <ag***@virtools.com> wrote in message
news:26**************************@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

call to
'A::foo(int)'.


or add a using directive to class B

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


This one is actually much nicer! Thanks for the hint!

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
Jul 19 '05 #4

P: n/a
Jakob Bieling wrote:
"AGoTH" <ag***@virtools.com> wrote in message
news:26**************************@posting.google.c om...
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 call to
'A::foo(int)'.


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.

Jul 19 '05 #5

P: n/a
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:3f33f6bd@shknews01...
Jakob Bieling wrote:
"AGoTH" <ag***@virtools.com> wrote in message
news:26**************************@posting.google.c om...
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 call to 'A::foo(int)'.


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*)'_.


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)
Jul 19 '05 #6

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


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
Jul 19 '05 #7

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


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
Jul 19 '05 #8

P: n/a
In article <BQeZa.106393$Ho3.13941@sccrnsc03>, v.********@attAbi.com
says...

[ ... ]
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.


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.
Jul 19 '05 #9

P: n/a
In article <BQeZa.106393$Ho3.13941@sccrnsc03>, v.********@attAbi.com
says...

[ ... ]
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.


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.
Jul 19 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.