Still a bit confused

K

Keith Willis

A few people have been asking about variants of this recently, and I'm
still not totally clear.

A class Base declares, amongst other things, a method called func().
Because derived classes might replace this with their own
implementation, func is declared as virtual in Base:

// header
class Base
{
public:
virtual int func(int arg1);
}

Because not all derived classes will wish to provide their own
implementation, Base provides a default one:

int
Base::func(int arg1)
{
......
}

This particular derived class in fact does not replace func():

class Derived : public Base
{
......
}

In the application code, I create a Derived object, and then call the
func() method:

{
Derived x;

int i = x.func(12345);
}

So, by my understanding, this is all fine, and indeed, testing it
works fine; the Base::func() is called exactly as I would expect, and
all is exactly as written in the FAQ-Lite Q20.6[1]. And If Derived
does declare a replacement with the same signature, then again, it all
works as expected, and the Derived version is called. But as soon as
Derived declares a func() member of its own, but with a totally
different signature, the Base version is hidden, and we have to have a
'using' clause in Derived to make it visible again. This is where I'm
stuck; surely, it should look up by the signature, then find
Base::func(int) through the vtable? Why does the damned thing get
hidden?

1.
http://www.ensta.fr/~diam/c++/online/c++-faq-lite/virtual-functions.html#faq-20.6
 
V

Victor Bazarov

Keith said:
[..Base declares virtual 'func()'..]
as soon as
Derived declares a func() member of its own, but with a totally
different signature, the Base version is hidden, and we have to have a
'using' clause in Derived to make it visible again. This is where I'm
stuck; surely, it should look up by the signature, then find
Base::func(int) through the vtable? Why does the damned thing get
hidden?

The lookup is NOT by the signature. The lookup is by the *name* only.
Does this help?

V
 
I

Ioannis Gyftos

My understanding is that it is done this way to prevent horrible bugs
that could show up when implicit type promotion/etc is involved.

For example, if you have Base::func(double x), and Derived::func(int
y) and you have something like:

Derived obj();
obj.func(1);

Which function is called? Which did you intend to call? It might be
easy to call the specific one you need in simple cases, but if you are
using a 3nd party library with deep levels of inheritance and you
derive some classes, you might not be aware of the existence of a
member function with the same name but different signature (and the
two functions could do totally different things, or worse, similar
ones with side-effects).

So, the decision to hide the base's function is done to protect the
programmer from such situations. If you use the "using" keyword, you
are declaring to the compiler that you are aware of the name clash,
and that you take responsibility for any implicit conversions.
 
K

Keith Willis

My understanding is that it is done this way to prevent horrible bugs
that could show up when implicit type promotion/etc is involved.
So, the decision to hide the base's function is done to protect the
programmer from such situations. If you use the "using" keyword, you
are declaring to the compiler that you are aware of the name clash,
and that you take responsibility for any implicit conversions.

Ahhhhhh! Now THAT actually makes sense.
Thanks you for the clarification.
 

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
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top