Overloading/Inheritance issue

Regan Heath regan at netmail.co.nz
Thu Aug 2 07:54:06 PDT 2007


Steve Schveighoffer wrote:
> Regan Heath Wrote:
> 
>> Steve gave an example in this very thread where the C++ behaviour
>> can cause errors for users/consumers of the classes so that would
>> count as a penalty for the C++ case.  Conversely you could argue
>> that at least this isn't a silent error as the problems Walter
>> describe are (from memory - pls correct me if I haven't remember it
>> correctly).
> 
> OK, I was totally under the impression that C++ was the way I was
> saying D should be.  

I suspect most people think C++ does it the way you suggested.

 > I was assuming that C++ got it right.  More than
> I can't believe that C++ is not right, I'm surprised I never had
> problems with it...

It's truly odd that no-one seems to have a problem with it in C++.  It's 
not as if C++ even has 'alias' so it cannot pull symbols in, you're left 
re-implementing in the derived class.  Perhaps everyone just does that 
without thinking about it.

> However, I think it should be changed.  Not sure if it will, as it
> seems there  is already a precedent.  In my opinion, the base class
> should be examined if the derived class does not provide a suitable
> match.  I can't see how this would cause too much of a performance
> hit

Performance isn't the reason against the Java behaviour, here is Walters 
explaination:

<quote Walter quoting Stroustrup>

Stroustrup gives two examples (slightly modified here):

---------------------------------
class X1 { void f(int); }

// chain of derivations X(n) : X(n-1)

class X9: X8 { void f(double); }

void g(X9 p)
{
     p.f(1);    // X1.f or X9.f ?
}
-----------------------------------
His argument is that one can easilly miss an overload of f() somewhere in a
complex class heirarchy, and argues that one should not need to understand
everything about a class heirarchy in order to derive from it. The other
example involves operator=(), but since D doesn't allow overloading
operator=() instead I'll rewrite it as if it were a function that needs to
alter a class state, and a derived class written later that 'caches' a
computation on the derived state:

class B
{    long x;
      void set(long i) { x = i; }
     void set(int i) { x = i; }
     long squareIt() { return x * x; }
}
class D : B
{
     long square;
     void set(long i) { B.set(i); square = x * x; }
     long squareIt() { return square; }
}

Now, imagine B were a complex class with a lot of stuff in it, and our
optimizing programmer missed the existence of set(int). Then, one has:

     long foo(B b)
     {
         b.set(3);
         return b.squareIt();
     }

and we have an obscure bug.

</quote>

So, as you can see it's not for performance reasons but rather to avoid 
obscure bugs which when they manifest do so silently.

Regan



More information about the Digitalmars-d mailing list