November 30, 2009
Andrei Alexandrescu wrote:
> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
> 
> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
> 
> class MyException : Exception {}
> 
> b) If a class defines at least one constructor, do not inherit constructors.
> 
> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
> 
> What do you think?

I like this. I think c should be a compile-time error.

Here's another use for annotations, in case you define new fields but still want to inherit the constructors:

@InheritConstructors
class Foo : Bar {
}
November 30, 2009
"Ary Borenszweig" <ary@esperanto.org.ar> wrote in message news:hf03ps$lk2$1@digitalmars.com...
> Andrei Alexandrescu wrote:
>> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
>>
>> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
>>
>> class MyException : Exception {}
>>
>> b) If a class defines at least one constructor, do not inherit constructors.
>>
>> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
>>
>> What do you think?
>

> I think c should be a compile-time error.
>

Why? (Not to be contentious.)


November 30, 2009
Don wrote:
> Andrei Alexandrescu wrote:
>> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
>>
>> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
>>
>> class MyException : Exception {}
>>
>> b) If a class defines at least one constructor, do not inherit constructors.
>>
>> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
>>
>> What do you think?
>>
>> Andrei
> 
> I would add: "and the class does not define a class invariant".
> 
> A constructor exists to establish the class invariant (even if that invariant is implicit). For (a), the old invariant will still be satisfied.
> In the case (c) there is a chance that the invariant will not be appropriate. In (c), I suggest that it is valid to inherit constructors if and only if the new class is a simple aggregate of the old class, together with the new members (which may have invariants of their own).
> If there's no constructor and no invariant, then either it's a simple aggregate, or it's a bug.
> 
> 

Good point. I do think of classes that add fields that don't mess up the invariant though:

class MyException : Exception {
    private int sysCode;
    invariant() { assert(sysCode < 100); }
}

If default initialization of the field puts it in a state that respects the invariant, there isn't a problem.


Andrei
November 30, 2009
Andrei Alexandrescu wrote:
> Don wrote:
>> Andrei Alexandrescu wrote:
>>> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
>>>
>>> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
>>>
>>> class MyException : Exception {}
>>>
>>> b) If a class defines at least one constructor, do not inherit constructors.
>>>
>>> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
>>>
>>> What do you think?
>>>
>>> Andrei
>>
>> I would add: "and the class does not define a class invariant".
>>
>> A constructor exists to establish the class invariant (even if that invariant is implicit). For (a), the old invariant will still be satisfied.
>> In the case (c) there is a chance that the invariant will not be appropriate. In (c), I suggest that it is valid to inherit constructors if and only if the new class is a simple aggregate of the old class, together with the new members (which may have invariants of their own).
>> If there's no constructor and no invariant, then either it's a simple aggregate, or it's a bug.
>>
>>
> 
> Good point. I do think of classes that add fields that don't mess up the invariant though:
> 
> class MyException : Exception {
>     private int sysCode;
>     invariant() { assert(sysCode < 100); }
> }
> 
> If default initialization of the field puts it in a state that respects the invariant, there isn't a problem.

Oh, that's an interesting one. If default initialization doesn't respect the invariant, the invariant is likely to catch it on first use anyway. So requiring no invariant probably wouldn't catch many bugs.

The fact that D does default initialization makes this whole issue much less perilous than in C++.

Returning to the original question:
Right now, constructors are inherited if they have no parameters. It's hard to see why the no-parameter case should be treated differently.
November 30, 2009
On 2009-11-29 18:03:40 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
> 
> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
> 
> class MyException : Exception {}
> 
> b) If a class defines at least one constructor, do not inherit constructors.
> 
> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
> 
> What do you think?

Objective-C has 'a' and 'c' acting like 'a'. There's no 'b' though, and this is a small annoyance, as "constructors" in Objective-C are just normal methods with a name that starts with "init".

Personally, I'd say adding a field to a class shouldn't affect its constructor. If you need to initialize the field at object's construction, then you add a constructor. But otherwise, if you don't need to initialize it at construction (which happens fairly often when fields are zeroed anyway), then you can certainly inherit super's constructors.

In fact, I find it hard to see a justification for making adding a field break constructor inheritance. My experience with Objective-C tells me that 'c' acting like 'a' wouldn't be a problem at all because D, just like Objective-C, initializes all fields to a default value anyway. You only need a constructor when you want a non-default value in a field.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

November 30, 2009
On 2009-11-30 10:30:11 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> class MyException : Exception {
>      private int sysCode;
>      invariant() { assert(sysCode < 100); }
> }
> 
> If default initialization of the field puts it in a state that respects the invariant, there isn't a problem.

I think this simply shows that if super's constructor is inherited, once the object is constructed invariant() should be called (and not super's invariant, the one of the object actually constructed). If you do that you'll catch any field not respecting the invariant right after construction.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

November 30, 2009
Andrei Alexandrescu Wrote:

> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
> 
> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
> 
> class MyException : Exception {}
> 
> b) If a class defines at least one constructor, do not inherit constructors.
> 
> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
> 
> What do you think?

I thought it was a great idea 2 years ago:

http://www.digitalmars.com/d/archives/digitalmars/D/Inheriting_constructors_54088.html

Haven't changed my mind since then :-)
November 30, 2009
Michel Fortin Wrote:

> On 2009-11-29 18:03:40 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
> > Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
> > 
> > a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
> > 
> > class MyException : Exception {}
> > 
> > b) If a class defines at least one constructor, do not inherit constructors.
> > 
> > c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
> > 
> > What do you think?
> 
> Objective-C has 'a' and 'c' acting like 'a'. There's no 'b' though, and this is a small annoyance, as "constructors" in Objective-C are just normal methods with a name that starts with "init".
> 
> Personally, I'd say adding a field to a class shouldn't affect its constructor. If you need to initialize the field at object's construction, then you add a constructor. But otherwise, if you don't need to initialize it at construction (which happens fairly often when fields are zeroed anyway), then you can certainly inherit super's constructors.
> 
> In fact, I find it hard to see a justification for making adding a field break constructor inheritance. My experience with Objective-C tells me that 'c' acting like 'a' wouldn't be a problem at all because D, just like Objective-C, initializes all fields to a default value anyway. You only need a constructor when you want a non-default value in a field.

I would hope that explicit out-of-ctor initialization would be allowed too:

class A : B
{
    // inherit B's ctors

    int x = 5;
}

Are there any instances where that calls an invisible ctor instead of just altering the init blob?
November 30, 2009
Nick Sabalausky wrote:
> "Ary Borenszweig" <ary@esperanto.org.ar> wrote in message news:hf03ps$lk2$1@digitalmars.com...
>> Andrei Alexandrescu wrote:
>>> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
>>>
>>> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
>>>
>>> class MyException : Exception {}
>>>
>>> b) If a class defines at least one constructor, do not inherit constructors.
>>>
>>> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
>>>
>>> What do you think?
> 
>> I think c should be a compile-time error.
>>
> 
> Why? (Not to be contentious.)

At first I thought you might want to add fields to a subclass for logging, or caching, stuff like that, while still wanting to inherit the constructors. Then I checked some code for a project I wrote in Java and always when the subclass had new fields it defined a different constructor, and the logging fields were static. So I think that most of the time you'd want to inherit the constructors when you don't define new fields.
December 01, 2009
Ary Borenszweig Wrote:

> Nick Sabalausky wrote:
> > "Ary Borenszweig" <ary@esperanto.org.ar> wrote in message news:hf03ps$lk2$1@digitalmars.com...
> >> Andrei Alexandrescu wrote:
> >>> Walter and I just discussed the matter of inheriting constructors. Our thought on the issue:
> >>>
> >>> a) If a class doesn't define any constructors and adds no fields, inherit constructors. Example:
> >>>
> >>> class MyException : Exception {}
> >>>
> >>> b) If a class defines at least one constructor, do not inherit constructors.
> >>>
> >>> c) If a class doesn't define any constructors but does add at least a non-static field -> undecided.
> >>>
> >>> What do you think?
> > 
> >> I think c should be a compile-time error.
> >>
> > 
> > Why? (Not to be contentious.)
> 
> At first I thought you might want to add fields to a subclass for logging, or caching, stuff like that, while still wanting to inherit the constructors. Then I checked some code for a project I wrote in Java and always when the subclass had new fields it defined a different constructor, and the logging fields were static. So I think that most of the time you'd want to inherit the constructors when you don't define new fields.

Since class member data is default initialized, I'm not sure I agree.  For example, let's say I want to modify a string class to add a search feature, and I want it to cache the prior result for performance reasons.  There's no need to ctor-initialize the result field, only to make sure it's null at the start.