How should overruling of overloaded functions work?

Kristian kjkilpi at gmail.com
Sat Aug 19 08:09:25 PDT 2006


Ok, this issue is controversaly. The following explains the situation fine:

http://groups.google.com/group/alt.comp.lang.learn.c-c++/msg/2bdda463aed5d153?hl=en&lr=lang_en&ie=UTF-8&oe=UTF-8&safe=off

In short, should the following work (without using the alias hack):

class Base {
     void f() {...}
     void f(int) {...}
}

class Derived : Base {
     void f() {...}
}

void func() {
     Derived obj = new Derived;

     obj.f(10);  //doesn't work
}

There were/are good reason(s) why it should not work (see the link).
I personally think it should work, though. There are a lot of people that  
think likewise. Of course, the other half think that it shouldn't work.


This is why I think it should work:

1)
If you like to change the behavior of the function altogether, then you  
should change all the overload functions. If a new overload is later added  
to the Base class, then you have to add the corresponding function to the  
Derived class. That is a problem, but hiding of overloads of Base doesn't  
work either. Why? See the point 2.


2)
Using the Derived class via the Base class will access the overloads  
defined in Base. For example:

class Base {
     void f(int v) {printf("%d\n", v);}
     void f(float v) {printf("%f\n", v);}
}

class Derived : Base {
     void f(int v) {printf("%d\n", -v);}
}

void func(Base obj) {
     obj.f(1);     //prints -1
     obj.f(1.0);   //prints 1.0, not -1.0
}

void main() {
     Derived obj = new Derived;

     func(obj);
}

We want that Derived changes the behavior of 'f()' so that it'll print  
positive values as negative ones and vice versa. If 'f()' is used in  
'main', the hiding of Base's 'f(float)' will prevent it being called.  
However, this restriction does not apply to inside 'func()'. 'f()' works  
incorrectly here: it prints a positive value for a float, which is not  
wanted. The programmer of course wants that 'f()' works consistent  
_throughout_ the code.

When 'f(float)' is added to Base, the corresponding function must also be  
added to Derived.


3)
If the overloading does not work for derived classes, then the following  
common case does not work without the alias hack:

class String {...}

class Base {
     void f(String s) {...}
     //these functions are provided for convenience...
     final void f(int v) {
         f(new String(v));
         }
     final void f(float v) {
         f(new String(v));
         }
}

class Derived : Base {
     void f(String s) {...}  //overrule the main function that does all the  
work
}

'f(int)' and 'f(float)' are hidden from Derived. You have to use aliasing,  
or the following coding style:

class Base {
     final void f(String s) {
         do_f(s);
         }
     final void f(int v) {
         do_f(new String(v));
         }
     final void f(float v) {
         do_f(new String(v));
         }

     void do_f(String s) {...}
}

class Derived : Base {
     void do_f(String s) {...}
}


4)
Aliasing nullifies the 'safety net' provided by the language. (Hence the  
safety net does not work.)


5)
The hiding of overloads in Derived works only partially, which is not a  
good thing, I think. It should work completely or not at all. In addition,  
cases where the hiding is not desirable are far more common (IMHO).



More information about the Digitalmars-d mailing list