Making inheritance less tedious

Kevin Bealer kevinbealer at gmail.com
Tue Feb 27 11:13:39 PST 2007


== Quote from Bill Baxter (dnewsgroup at billbaxter.com)'s article
> Kevin Bealer wrote:
> > Kristian Kilpi wrote:
> >>
> >> I think class inheritance is a bit(?) tedious sometimes (that is,
> >> unnecessarily tedious).
> >> (I leave interfaces out of this discussion.) 'Problems', IMHO, with it
> >> are:
> >>
> >> 1) You cannot inherit constructors.
> >>
> >
> > As for (1), I agree and this is something that annoys me in C++ too.
> So what would be the effect of calling a base class constructor?
> I guess it would have to call the base constructor followed by the
> derived class's default constructor?
> It seems like that could cause headaches.  Maybe that's why C++ doesn't
> allow it.  Especially in D where the default constructor may already
> call the base constructor.
> class Base
> {
>     this(int a, float b) {
>       m_a = a;
>       m_b = b;
>     }
>     int m_a;
>     float m_b;
> }
> class Derived : Base
> {
>     this() {
>        super(2,3.0f);
>        mString = "Happy happy";
>     }
>     this(int a) {
>        super(a,6.0f);
>        mString = "howdy howdy";
>     }
>     char[] mString;
> }
> void main()
> {
>     Derived x = new Derived(a,b);
>     // what got called exactly?
>     // and what values do x.m_a and x.m_b have now?
> }
> --bb

My proposal is that you need to use "alias" or something like it to inherit the
constructors.  You clipped this part out but this is the syntax:

class X : Y {
     alias Y.this this;
}

So for my proposal, your example would just be a syntax error, unless you add the
'alias' statement shown here.

If you *did* add "alias Base.this this", then D would add this definition to Derived:

class Derived : Base {
    ...
    this(int a, int b)
    {
        super(a, b);
    }
    ...
}

It would keep your other constructors and methods just as they are.  If you want
to make sure the mString is set, then you would not want to use this feature.

I've often thought that in C++ I could achieve neat results by copying the vector,
string, and map classes and adding my own functionality, but there is the
annoyance of duplicating the half dozen or so string constructors.  The simplest
c++ syntax I have found is this (not tested):

class MyString : string {
public:
    template<A>   MyString(A x) : string(x) {}
    template<A,B>  MyString(A x, B y) : string(x,y) {}
    template<A,B,C> MyString(A x, B y, C z) : string(x,y,z) {}
};

I think of this as a 'forwarding' technique.  It's covers all methods with a
certain number of parameters.  I don't have to worry about (char*,char*) and
(iterator,iterator) or whatever because they are both covered by the above 2-input
syntax.

(I don't know how well this works for in,out,inout, or their C++ equivalents.)

However, since the only thing I'm doing in that code is duplicating the string()
methods, it would be neat if I could just do this:

class MyString : string {
public:
    using string::string; // or whatever
};

Kevin



More information about the Digitalmars-d mailing list