Topic: Why Hide? (was: Question overloading methods)


Author: mitek@nic.cerf.net (Mitek Systems)
Date: 7 Mar 1994 15:17:22 GMT
Raw View
jean-claude.bourut@gsi.fr (JClaude Bourut) writes:


>I have a set of classes that inherit from a root class named Storable. A
>second set of classes inherit from another class named IC. Each IC class
>contains a method check taking one storable subclass as parameter:

>class StorableA : public Storable { ... } ;
>class StorableB : public Storable { ... } ;
>class StorableC : public Storable { ... } ;


>class IC_A : public IC { ... check( StorableA &) ;  } ;
>class IC_B : public IC { ... check( StorableB &) ;  } ;
>class IC_C : public IC { ... check( StorableC &) ;  } ;


>Appart different signature, these methods do exactly the same job with the
>same kind of parameter. For the rest of my lib, I cast back and forth Storable
>to one of its subclass. But here, I must call various APIs. I would like all
>these check methods to overload a check method in my IC root class.

>I already know, I could use a generic method named check( Storable &), but
>this would not be a correct API to people writing the body of these methods.

>Do you feel this correct ?
>Do you have any suggestion to achieve this ?

>Thanks

First, your check methods in the derived classes _override_ any check
method in the base class since they have different arguments.  THe
difference between _overload_ and override is, I believe, important
and often overlooked.  Overloading happens when two (or more) functions
_in the same scope_ have different arguments but the same name (ARM 13).

Overriding happens when a derived class declares a function with the
same name as that of a function in the base class, regardless of
arguments.  The derived class function is said to "hide" the base
class function (ARM 13.1).

The reasons for this are somewhat murky to me, but basically it's to
avoid "unintentional overloading of unrelated functions" (from
the ARM).  The example given is a derived class with f(double) and
a base class with f(int).  The hiding rule is an attempt to avoid
having something like "f(2)" cause compiler/programmer misunderstanings
and unexpected results.

The hiding rule is unfortunate, however, because it is sometimes the case
that one wants to add functions in a derived class that overload
base class functions without overriding them.  For example,

 class File {
  virtual int read(char*, int);
 }

 class FooFile : File {
  int read(Foo*, int);
 }

Despite the fact that (in this case) there is no way for the compiler
to mistake a Foo* for a char*, FooFile::read() hides File::read().
This _may_ in fact be what you want, but that means you can't read
a FooFile by characters unless you declare and define a FooFile::read()
that takes the same arguments as that in File.  Given the rule as it is,
good compilers will warn about the hiding.

shane
jsm@miteksys.com