digitalmars.D - Constructor inheritance & polish function
Let there be classes Base and Derived. Base is the base class of Derived= . There are several constructors in Base. Derived can have constructors as= follows: 1) Derived has only the default constructor which calls 'Base.this()' if= it exists. 2) Derived uses the same constructor interface as Base. The constructors= are not modified in any way (i.e. they simply call the ones in Base). 3) Derived uses the same constructor interface as Base. Some or all of t= he constructers are modified. 4) Derived uses different constructor interface as Base. To my experience the commonness of the situations is: 2, 3, 4, and 1. So constructors should be inherited from the base class. For example: class Base { this() {...} this(int val) {...} void f() {...} } class Derived : Base { void f() {...} //overrule a member function } void func() { Derived obj =3D new Derived(1); //calls 'Base.this(int)' (now a c= ompile time error) } It would make the case 2 breeze to implement! If you define constructors for Derived, then the ones defined in Base should be hidden. The case 1 could be achieved by defining one constructor: 'this() {}'. If there was a polish function (just like one in Qt) which is called aft= er a constructor is finished, it would save unnecessary constructor writing= in some cases. It would be especially useful when Derived is using the same constructor interface as Base (case 2) except the constructors shou= ld do something additional also (subtype of case 3). For example: class Base { this() { m_val =3D -1; } this(int val) { m_val =3D val; } void f() { m_val =3D 100; } int m_val; } class Derived : Base { this_polish() { //is called after a constructor f(); } } void func() { Derived obj =3D new Derived(1); //'obj.m_val' =3D=3D 100 (first 1= , then = 100) } This would reduce redundant code, which is a possible source for typos a= nd errors. It would also be easier to maintain: if parameter lists of Base'= s constructors are modified, no changes will be required for Derived.
Aug 21 2006
I forgot to mention that this would not break the old code. I can't think any reason why this is not implemented in D (or in C++). = Maybe someone could enlighten me on this? Surely it'll make subclassing = = easier and more bug free. The overload function hiding rule does not app= ly = here. That is, changing the constructors of Base won't break the = constructors of Derived (because they just call the ones of Base). If someone would prefer a (little) better example, here's a one: class Button { this(...) {...} this(...) {...} //and zillion other constructors... void paint() {...} //paints the button on the screen } Now we'll need a button that paints a cross over the button in some = situations: class MyButton : Button { void paint() { super.paint(); if(m_is_crossed) { //paint the cross ... } } bool m_is_crossed =3D false; } No need to rewrite (copy&paste + modify) those zillion constructors of = Button. If a more complex initialization should be done (i.e. in addition of "bo= ol = m_is_crossed =3D false;"), then the polish function would be candy. On Mon, 21 Aug 2006 10:39:31 +0300, Kristian <kjkilpi gmail.com> wrote:Let there be classes Base and Derived. Base is the base class of Deriv=ed. [snip]class Base { this() {...} this(int val) {...} void f() {...} } class Derived : Base { void f() {...} //overrule a member function } void func() { Derived obj =3D new Derived(1); //calls 'Base.this(int)' (now a==compile time error) }[snip]class Derived : Base { this_polish() { //is called after a constructor f(); } } void func() { Derived obj =3D new Derived(1); //'obj.m_val' =3D=3D 100 (first=1, then =100) } This would reduce redundant code, which is a possible source for typos==and errors. It would also be easier to maintain: if parameter lists of Bas=e'sconstructors are modified, no changes will be required for Derived.
Aug 21 2006