Explain this 
July 22nd, 2005, 11:31 PM
| | | Explain this
Hello
Here is a short code snippet which does not compile. Could someone
explain why this is ?
class A
{
public:
void set(int a)
{
v[0] = a;
v[1] = a;
}
int v[2];
};
class B: public A
{
public:
void set(int a, int b)
{
v[0] = a;
v[1] = b;
}
};
int main()
{
B b;
b.set(2);
return 0;
} | 
July 22nd, 2005, 11:31 PM
| | | Re: Explain this
On Sat, 08 Jan 2005 23:30:21 +0200, Kalle Rutanen <none@here.com>
wrote:
[color=blue]
>Hello
>
>Here is a short code snippet which does not compile. Could someone
>explain why this is ?
>
>class A
>{
>public:
> void set(int a)
> {
> v[0] = a;
> v[1] = a;
> }
> int v[2];
>};
>
>class B: public A
>{
>public:
> void set(int a, int b)
> {
> v[0] = a;
> v[1] = b;
> }
>};
>
>int main()
>{
> B b;
> b.set(2);
> return 0;
>}[/color]
Is this homework?
--
Bob Hairgrove NoSpamPlease@Home.com | 
July 22nd, 2005, 11:31 PM
| | | Re: Explain this
"Kalle Rutanen" <none@here.com> wrote in message
news:crpjda$13lb$1@news.cc.tut.fi...[color=blue]
> Hello
>
> Here is a short code snippet which does not compile. Could someone
> explain why this is ?
>
> class A
> {
> public:
> void set(int a)
> {
> v[0] = a;
> v[1] = a;
> }
> int v[2];
> };
>
> class B: public A
> {
> public:
> void set(int a, int b)[/color]
Takes two arguments.
[color=blue]
> {
> v[0] = a;
> v[1] = b;
> }
> };
>
> int main()
> {
> B b;
> b.set(2);[/color]
You only gave one argument.
[color=blue]
> return 0;
> }[/color]
My compiler's error message makes the problem very clear:
error C2660: 'set' : function does not take 1 parameters
-Mike | 
July 22nd, 2005, 11:31 PM
| | | Re: Explain this
* Kalle Rutanen:[color=blue]
>
> Here is a short code snippet which does not compile. Could someone
> explain why this is ?
>
> class A
> {
> public:
> void set(int a)
> {
> v[0] = a;
> v[1] = a;
> }
> int v[2];
> };
>
> class B: public A
> {
> public:
> void set(int a, int b)
> {
> v[0] = a;
> v[1] = b;
> }
> };
>
> int main()
> {
> B b;
> b.set(2);
> return 0;
> }[/color]
The declaration of B::set hides the base class A::set.
You can add
using A::set;
in class B.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail? | 
July 22nd, 2005, 11:31 PM
| | | Re: Explain this
Kalle Rutanen wrote:
[color=blue]
> Hello
>
> Here is a short code snippet which does not compile. Could someone
> explain why this is ?
>
> class A
> {
> public:
> void set(int a)
> {
> v[0] = a;
> v[1] = a;
> }
> int v[2];
> };
>
> class B: public A
> {
> public:
> void set(int a, int b)
> {
> v[0] = a;
> v[1] = b;
> }
> };
>
> int main()
> {
> B b;
> b.set(2);
> return 0;
> }[/color]
Alternatively, you could call b.A::set(2) in main() [SOME compilers used
to be quite clear that the derived class definition HID the base class
definition if the arguments were different.]
Dan | 
July 22nd, 2005, 11:32 PM
| | | Re: Explain this
> Is this homework?
Is not;) | 
July 22nd, 2005, 11:32 PM
| | | Re: Explain this
> The declaration of B::set hides the base class A::set.[color=blue]
>
> You can add
>
> using A::set;
>
> in class B.[/color]
Having read a reference C++ book, I noticed that this is due to name
lookup. Compilers first look for the matching name in class hierarchy
and then try to match parameters.
Your solution of using "using" is what I needed, thank you;)
As a theoretical question: Why do you think they (the C++ standard
committee) made the decision (in this inheritance situation) to hide
functions by name rather than "normally" by name and parameters (it
seems a bit unlogical) ? | 
July 22nd, 2005, 11:32 PM
| | | Re: Explain this
> Alternatively, you could call b.A::set(2) in main() [SOME compilers used[color=blue]
> to be quite clear that the derived class definition HID the base class
> definition if the arguments were different.][/color]
Thank you. As a reply, please see the reply I posted to Alf P. Steinbach
to avoid repeating;) | 
July 22nd, 2005, 11:32 PM
| | | Re: Explain this
> > class A[color=blue][color=green]
> > {
> > public:
> > void set(int a)[/color][/color]
Takes one argument.
[color=blue][color=green]
> > {
> > v[0] = a;
> > v[1] = a;
> > }
> > int v[2];
> > };
> >
> > class B: public A[/color][/color]
Inherits the one-argument set from A.
[color=blue][color=green]
> > {
> > public:
> > void set(int a, int b)[/color]
>
> Takes two arguments.
>[color=green]
> > {
> > v[0] = a;
> > v[1] = b;
> > }
> > };
> >
> > int main()
> > {
> > B b;
> > b.set(2);[/color]
>
> You only gave one argument.[/color]
...but B contains also the one-argument set inherited from A.
Anyway, thanks for the effort, and please see the reply I posted to Alf.
P Steinbach to avoid repeating;) | 
July 22nd, 2005, 11:32 PM
| | | Re: Explain this
> As a theoretical question: Why do you think they (the C++ standard[color=blue]
> committee) made the decision (in this inheritance situation) to hide
> functions by name rather than "normally" by name and parameters (it
> seems a bit unlogical) ?[/color]
Doing otherwise would have been inconsistent with the rest of the name
lookup rules. Just for example:
char x;
void f() {
int x;
x = 'a';
}
At least in C and C++, the fact that we're assigning a char to x
doesn't mean that the assignment is really to the global x. The x that
is visible inside the function is the one that's defined inside of the
function, and the type we're assigning doesn't change that.
If this was changed, it would also cause a serious difference between C
and C++ in a different way: in C, a character literal has type int,
where in C++ it has type char. As such, if the name lookup was done
this way, compiling this as C would assign to the local variable, but
compiling it as C++ would assign to the global.
Changing this rule also makes lot of code relatively fragile. For
example:
class X {
int f(int);
int g() { f('a'); }
}
I _know_ that X::g() calls X::f(), implicitly casting the char to an
int before doing so. Some would argue that this implicit conversion is
undesirable, but at least I know what's going to happen -- and since
it's widening a char to an int, the conversion is fairly safe.
Consider what happens if the function signature worked across block
scopes though: if there was a global function f(char), it would get
called in preference to X::f().
While these problems may be less obvious when inheritance is involved,
I think there would be serious problems there as well. Consider, for
example:
class base {
void utility(char);
};
class derived : public base {
void utility(int);
void g() {
utility('a');
};
Now, in this case it seems likely that the programmer _intended_ to
call derived::utility -- in fact, he might not be consciously aware
that the base class even contains a function by that name (since it's
private, he shouldn't have to be). Unfortunately, he's passing a char
instead of an int, so if base::utility was visible it would be the
better match (and since it's not accessible, the code wouldn't
compile).
In this particular case, that could be "cured" by changing that rule as
well, so that 'private' functions would be invisible rather than
inaccessible in a derived class.
Knowing how things go, however, there are almost certainly a few other
things that depend on that rule being the way it is -- and each of them
undoubtedly has a few more dependencies, and so on. You could
undoubtedly create a coherent language with these things changed, but
the result wouldn't be a C++ that was marginally different in one
particular area, but a language that was considerably different
throughout.
Compiling this language would be considerably more difficult -- in
fact, compiling ordinary code would become somewhat similar to
compiling an exported template with the current language, and for much
the same reason: the meaning of a particular name wouldn't be defined
entirely by the code itself, but by the entire context within which the
code was used. Likewise, many of the surprising things that can arise
with two-phase name lookup in an exported template could then affect
non-template code as well. Rather than being able to read and
understand code in small, digestible chunks, you'd have to read and
(sort of) undertand all the context before any one piece could be
understood.
--
Later,
Jerry.
The universe is a figment of its own imagination. | 
July 22nd, 2005, 11:32 PM
| | | Re: Explain this
"Kalle Rutanen" <none@here.com> wrote in message
news:crr33e$1lac$1@news.cc.tut.fi...[color=blue][color=green][color=darkred]
> > > class A
> > > {
> > > public:
> > > void set(int a)[/color][/color]
>
> Takes one argument.
>[color=green][color=darkred]
> > > {
> > > v[0] = a;
> > > v[1] = a;
> > > }
> > > int v[2];
> > > };
> > >
> > > class B: public A[/color][/color]
>
> Inherits the one-argument set from A.
>[color=green][color=darkred]
> > > {
> > > public:
> > > void set(int a, int b)[/color]
> >
> > Takes two arguments.[/color][/color]
... and since the signature is different, but the name
is the same, hides the 'set' from 'A'.
[color=blue][color=green]
> >[color=darkred]
> > > {
> > > v[0] = a;
> > > v[1] = b;
> > > }
> > > };
> > >
> > > int main()
> > > {
> > > B b;
> > > b.set(2);[/color]
> >
> > You only gave one argument.[/color]
>
> ..but B contains also the one-argument set inherited from A.[/color]
... and you hid it by giveing a different function the same name.
This is C++, not 'hide and seek'. :-)
-Mike | 
July 22nd, 2005, 11:35 PM
| | | Re: Explain this
Jerry Coffin wrote:
[color=blue][color=green]
> > As a theoretical question: Why do you think they (the C++ standard
> > committee) made the decision (in this inheritance situation) to hide
> > functions by name rather than "normally" by name and parameters (it
> > seems a bit unlogical) ?[/color]
>
> Doing otherwise would have been inconsistent with the rest of the name
> lookup rules. Just for example:[/color]
Thank you for an excellent explanation! | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 220,840 network members.
|