Connecting Tech Pros Worldwide Help | Site Map

Explain this

  #1  
Old July 23rd, 2005, 12:31 AM
Kalle Rutanen
Guest
 
Posts: n/a
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;
}
  #2  
Old July 23rd, 2005, 12:31 AM
Bob Hairgrove
Guest
 
Posts: n/a

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
  #3  
Old July 23rd, 2005, 12:31 AM
Mike Wahler
Guest
 
Posts: n/a

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


  #4  
Old July 23rd, 2005, 12:31 AM
Alf P. Steinbach
Guest
 
Posts: n/a

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?
  #5  
Old July 23rd, 2005, 12:31 AM
Dan Platt
Guest
 
Posts: n/a

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
  #6  
Old July 23rd, 2005, 12:32 AM
Kalle Rutanen
Guest
 
Posts: n/a

re: Explain this


> Is this homework?

Is not;)
  #7  
Old July 23rd, 2005, 12:32 AM
Kalle Rutanen
Guest
 
Posts: n/a

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) ?
  #8  
Old July 23rd, 2005, 12:32 AM
Kalle Rutanen
Guest
 
Posts: n/a

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;)
  #9  
Old July 23rd, 2005, 12:32 AM
Kalle Rutanen
Guest
 
Posts: n/a

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;)
  #10  
Old July 23rd, 2005, 12:32 AM
Jerry Coffin
Guest
 
Posts: n/a

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.

  #11  
Old July 23rd, 2005, 12:32 AM
Mike Wahler
Guest
 
Posts: n/a

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


  #12  
Old July 23rd, 2005, 12:35 AM
Kalle Rutanen
Guest
 
Posts: n/a

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!

Closed Thread


Similar Threads
Thread Thread Starter Forum Replies Last Post
plz explain this ????? dmjpro answers 6 March 20th, 2007 04:46 PM
explain this..... muttaa answers 24 March 22nd, 2006 01:15 PM
IIS 6 security - anyone can explain this for me ? Michael Tsai answers 3 November 19th, 2005 06:05 PM
Explain this ! Ravi Uday answers 2 November 14th, 2005 10:58 AM
Can someone explain this error to me? :( Maciej Nadolski answers 11 July 17th, 2005 01:26 AM