Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rationale for overloaded Derived function hiding Base function

425 views
Skip to first unread message

Bruce T

unread,
May 3, 2001, 3:26:45 AM5/3/01
to
Hello,

I wanted to find some information on the rationale behind why C++ was
designed with the mechanism that a Derived class that
provides a function with a different signature or return type, hides a base
class function of the same name. I undestand
the mechanism and how it works and how to get around it but I wanted to know
if there were any links/articles/info
that describe the rationale behind the why this is part of the language.

Thanks in advance,
Bruce

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Francis Glassborow

unread,
May 3, 2001, 7:20:48 PM5/3/01
to
In article <9cp33t$9c5$1...@bob.news.rcn.net>, Bruce T
<btr...@contactsystems.com> writes

>I wanted to find some information on the rationale behind why C++ was
>designed with the mechanism that a Derived class that
>provides a function with a different signature or return type, hides a base
>class function of the same name. I undestand
>the mechanism and how it works and how to get around it but I wanted to know
>if there were any links/articles/info
>that describe the rationale behind the why this is part of the language.

Basically it is a name look-up problem. Where should the compiler look
for names?

FWIW one possible change to C++ will be to do something to prevent
accidental hiding of virtual functions. The details and scope of the
change are yet to be considered.


Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Carl Daniel

unread,
May 4, 2001, 9:07:50 AM5/4/01
to
See D&E, 3.5.3 for Mr. Stroustrup's take on why overrides hide functions in
the base class.
-cd

"Bruce T" <btr...@contactsystems.com> wrote in message
news:9cp33t$9c5$1...@bob.news.rcn.net...

Robert O'Dowd

unread,
May 4, 2001, 9:08:56 AM5/4/01
to
Bruce T wrote:
>
> Hello,
>
> I wanted to find some information on the rationale behind why C++ was
> designed with the mechanism that a Derived class that
> provides a function with a different signature or return type, hides a base
> class function of the same name. I undestand
> the mechanism and how it works and how to get around it but I wanted to know
> if there were any links/articles/info
> that describe the rationale behind the why this is part of the language.
>

IIRC, the argument was based on something like

Let's say we have a class

class MyClass
{
public:

void function(double);
};

When we use x->function(0) for x pointing to MyClass we
always expect the 0 to be treated as a double.

Now, some time down track, we decide to modify MyClass, so
it inherits from a useful base class

class MyClass : public UsefulBase
{
public:

void function(double);
};

But, consider the case where UsefulBase gives something like

class UsefulBase
{
public:

void function(int);
};

Now, consider the effect of this on the following code

int main()
{
MyClass object;
object.function(0);
return 0;
}

without the hiding rule, our change to the structure of
MyClass would silently mean we are calling UsefulBase::function
rather than MyClass::function, as the function is now overloaded.
This can introduce unforeseen, and difficult to find, changes of
behaviour, particularly if you have a large code base that uses
MyClass.

IMHO, like most rules of this type, this one is a double edged
sword. If your system design calls for overloading, then the
hiding rule has to be worked around.

Sorin Jianu

unread,
May 4, 2001, 10:44:21 AM5/4/01
to

"Bruce T" <btr...@contactsystems.com> wrote in message
news:9cp33t$9c5$1...@bob.news.rcn.net...
> Hello,
>
> if there were any links/articles/info
> that describe the rationale behind the why this is part of the language.
>

There is some information in C++PL 3rd edition, 7.4.2 Overloading and
scopes. In the C++ standard, chapter 13 is dedicated to overloading.

On a personal note, I would say that the reason overloading doesn't work
across different scopes is to avoid unintentional hiding as a source of
surprises.

Sorin

James Dennett

unread,
May 4, 2001, 10:56:21 AM5/4/01
to
Bruce T wrote:
>
> Hello,
>
> I wanted to find some information on the rationale behind why C++ was
> designed with the mechanism that a Derived class that
> provides a function with a different signature or return type, hides a base
> class function of the same name. I undestand
> the mechanism and how it works and how to get around it but I wanted to know
> if there were any links/articles/info
> that describe the rationale behind the why this is part of the language.

I think the normal example is like this:

#include <cassert>

struct Base {

};

struct Derived {
bool doSomething(long) { return true; }
};

int main() {
Derived d;
assert(d.doSomething(1));
}

Now a helpful programmer comes along and adds a method to
Base:

struct Base {
bool doSomething(int) { return false; }
};

Under current rules, the code continues to work, as the
call still invokes Derived::doSomething (which returns
true). If Base::doSomething was implicitly added to the
set of visible functions for overload resolution then
the code would break.

I'm not sure that I find this argument persuasive;
changing a base class does tend to be a fragile operation.
On the other hand, without the current rules even adding
a private helper method to a base class could cause code
to stop compiling (because overload resolution would
choose the base class method and then access control
would rule the call illegal).

-- James Dennett

Carl Manaster

unread,
May 4, 2001, 2:46:52 PM5/4/01
to
Thank you, Robert, for a helpful explanation.

--Carl


In article <3AF20C07...@nonexistant.com>, Robert O'Dowd
<nos...@nonexistant.com> wrote:

> without the hiding rule, our change to the structure of
> MyClass would silently mean we are calling UsefulBase::function
> rather than MyClass::function, as the function is now overloaded.
> This can introduce unforeseen, and difficult to find, changes of
> behaviour, particularly if you have a large code base that uses
> MyClass.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

James Kanze

unread,
May 4, 2001, 2:49:55 PM5/4/01
to
Bruce T wrote:

> I wanted to find some information on the rationale behind why C++
> was designed with the mechanism that a Derived class that provides a
> function with a different signature or return type, hides a base
> class function of the same name. I undestand the mechanism and how
> it works and how to get around it but I wanted to know if there were
> any links/articles/info that describe the rationale behind the why
> this is part of the language.

The reason is safety. Consider the following code:

In a header somewhere:

struct Base
{
void foo( char ) ;
} ;

Part of my application:

struct Derived : Base
{
void foo( char ) ;
}

Derived d ;

if ( cin.peek() != EOF ) {
d.foo( cin.get() ) ;
}

This works exactly as expected: the function called is
Derived::foo(char).

Now what happens if the author of Base (who knows nothing of my
derived) adds a function:
void foo( int ) ;
With the C++ rules, exactly nothing. Everything still works as
before. If the foo in Derived didn't hide all foo in Base, however,
the above code would call the new Base::foo, which was not the initial
intend, and will probably cause a subtle bug.

Whether this is a real problem or not is debatable. Typically, any
changes in a base class requires that all derived classes be
scrutinized anyway. But C++ chose the safe alternative. There is
also the question of what would happen if the added function were
private. Changes in the private parts of Base should NOT affect
Derived; without the hiding, however, the code for Derived becomes
illegal.

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

Andrei Alexandrescu

unread,
May 5, 2001, 7:12:08 PM5/5/01
to
"James Dennett" <jden...@acm.org> wrote in message
news:3AF1D562...@acm.org...
[explanation of name hiding snipped]

> I'm not sure that I find this argument persuasive;
> changing a base class does tend to be a fragile operation.

The more I think of it, the less persuasive I find it. I lived all my life
believing name hiding is good and wise. Now I look back at my wasted life
:o).

Consider we slightly change the example.

Do people consider free functions that take and/or return a Foo (through
reference, pointer etc.) part of Foo's interface? Well, according to Koenig
lookup and Herb Sutter's work, the answer is yes. Friend free functions are
an obvious example; operators are another.

If we agree on that, then all of a sudden we found a gratuitous
incompatibility between member and nonmember functions; the latter are not
affected by name hiding.

Because of this gratuitous incompatibility Loki had to go through 'friend'
contortions to implement PrototypeFactoryUnit (see AbstractFactory.h).

> On the other hand, without the current rules even adding
> a private helper method to a base class could cause code
> to stop compiling (because overload resolution would
> choose the base class method and then access control
> would rule the call illegal).

That's why member functions should be banned altogether :oO.


Andrei

Carlos Moreno

unread,
May 6, 2001, 9:31:15 AM5/6/01
to

Andrei Alexandrescu wrote:
>
> That's why member functions should be banned altogether :oO.

No please! Don't do that to me!!! (that would mean that I would
have no choice but to move to Java... AARRRRRGHHHH!!!! :-))

Carlos
--

Risto Lankinen

unread,
May 7, 2001, 6:52:40 AM5/7/01
to
Hi!

Andrei Alexandrescu <andre...@hotmail.com> wrote in message
news:9d1fpb$g2ojd$1...@ID-14036.news.dfncis.de...


> Do people consider free functions that take and/or return a Foo (through
> reference, pointer etc.) part of Foo's interface? Well, according to
Koenig
> lookup and Herb Sutter's work, the answer is yes. Friend free functions
are
> an obvious example; operators are another.
>
> If we agree on that, then all of a sudden we found a gratuitous
> incompatibility between member and nonmember functions; the latter are not
> affected by name hiding.

Are too! Given...

void f( int ) { cout << "int"; }
void f( long ) { cout << "long"; }

... then...

void g()
{
f( 0 );
}

... and...

void g()
{
void f( long );
f( 0 );
}

... behave differently. Clearly the latter example hides
'void f(int)' which is, as you call it, a free function.

Cheers!

- Risto -

0 new messages