Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
September 23, 2015 Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
[code] import std.stdio; class B { this() { writeln("B.constructor"); foo(); } void foo() { writeln("B.foo"); } } class D : B { this() { writeln("D.constructor"); } override void foo() { writeln("D.foo overrides B.foo"); } } void main() { auto b = new D(); } [/code] Result: B.constructor D.foo overrides B.foo D.constructor ---- There is no use of "super()" in the constructor of D, yet B's constructor is called when D is created. Why is that so? I changed the constructor of D as follows: [code] this() { super(); writeln("D.constructor"); } [/code] Results haven't changed at all. "super()" doesn't make any difference. What's going on? I wouldn't expect B's constructor to be called at all unless "super" is used there. |
September 23, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to tcak | On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote: > I wouldn't expect B's constructor to be called at all unless "super" is used there. "If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. " from http://dlang.org/class.html#constructors the idea is to make sure the base class construction work is done too. |
September 23, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote:
> On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote:
>> I wouldn't expect B's constructor to be called at all unless "super" is used there.
>
> "If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. "
>
>
> from http://dlang.org/class.html#constructors
>
> the idea is to make sure the base class construction work is done too.
Is there any way to prevent this behaviour?
Quickly checked whether Java acts in the same way. Answer is yes.
|
September 23, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to tcak | On 09/23/2015 02:25 PM, tcak wrote: > On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote: >> On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote: >>> I wouldn't expect B's constructor to be called at all unless "super" >>> is used there. >> >> "If no call to constructors via this or super appear in a constructor, >> and the base class has a constructor, a call to super() is inserted at >> the beginning of the constructor. " >> >> >> from http://dlang.org/class.html#constructors >> >> the idea is to make sure the base class construction work is done too. > > Is there any way to prevent this behaviour? No and I don't think it will ever be implemented. The derived class is supposed to be used as the super class, which involves proper construction of the super parts. > Quickly checked whether Java acts in the same way. Answer is yes. Same with C++. As discussed in the other thread, at least D allows changing the order in which the super constructor is executed. Ali |
September 23, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wed, Sep 23, 2015 at 03:25:04PM -0700, Ali Çehreli via Digitalmars-d-learn wrote: > On 09/23/2015 02:25 PM, tcak wrote: > >On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote: > >>On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote: > >>>I wouldn't expect B's constructor to be called at all unless "super" is used there. > >> > >>"If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. " > >> > >> > >>from http://dlang.org/class.html#constructors > >> > >>the idea is to make sure the base class construction work is done too. > > > >Is there any way to prevent this behaviour? > > No and I don't think it will ever be implemented. The derived class is supposed to be used as the super class, which involves proper construction of the super parts. [...] I can't think of any valid use case for not running the base class ctor. Are you sure you aren't violating the Liskov Substitution Principle in some way? It may be that what you need is a has-a relationship rather than an is-a relationship in your class. T -- Once the bikeshed is up for painting, the rainbow won't suffice. -- Andrei Alexandrescu |
September 24, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to tcak | On Wednesday, 23 September 2015 at 21:25:15 UTC, tcak wrote:
> On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote:
>> On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote:
>>> I wouldn't expect B's constructor to be called at all unless "super" is used there.
>>
>> "If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. "
>>
>>
>> from http://dlang.org/class.html#constructors
>>
>> the idea is to make sure the base class construction work is done too.
>
> Is there any way to prevent this behaviour?
>
> Quickly checked whether Java acts in the same way. Answer is yes.
You might be able to swap out the vtbl entry for a stub call it and trick the compiler and swap it back, but...
|
September 24, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On Thursday, 24 September 2015 at 01:01:09 UTC, Nicholas Wilson wrote:
> On Wednesday, 23 September 2015 at 21:25:15 UTC, tcak wrote:
>> On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote:
>>> On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote:
>>>> I wouldn't expect B's constructor to be called at all unless "super" is used there.
>>>
>>> "If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. "
>>>
>>>
>>> from http://dlang.org/class.html#constructors
>>>
>>> the idea is to make sure the base class construction work is done too.
>>
>> Is there any way to prevent this behaviour?
>>
>> Quickly checked whether Java acts in the same way. Answer is yes.
>
> You might be able to swap out the vtbl entry for a stub call it and trick the compiler and swap it back, but...
Urgh...
If you can modify the base class, and you really need it, you can check the dynamic type:
class Base {
this() {
if(!cast(Base) this) return;
// do the initialization
}
}
|
September 24, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Thursday, 24 September 2015 at 11:26:12 UTC, Marc Schütz wrote:
> On Thursday, 24 September 2015 at 01:01:09 UTC, Nicholas Wilson wrote:
>> On Wednesday, 23 September 2015 at 21:25:15 UTC, tcak wrote:
>>> On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote:
>>>> [...]
>>>
>>> Is there any way to prevent this behaviour?
>>>
>>> Quickly checked whether Java acts in the same way. Answer is yes.
>>
>> You might be able to swap out the vtbl entry for a stub call it and trick the compiler and swap it back, but...
>
> Urgh...
>
> If you can modify the base class, and you really need it, you can check the dynamic type:
>
> class Base {
> this() {
> if(!cast(Base) this) return;
> // do the initialization
> }
> }
doesn't upcasting always work? iirc only down casting can return null.
|
September 24, 2015 Re: Why is the constructor of B called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On 09/24/15 13:26, Marc Schütz via Digitalmars-d-learn wrote:
> On Thursday, 24 September 2015 at 01:01:09 UTC, Nicholas Wilson wrote:
>> On Wednesday, 23 September 2015 at 21:25:15 UTC, tcak wrote:
>>> On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote:
>>>> On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote:
>>>>> I wouldn't expect B's constructor to be called at all unless "super" is used there.
>>>>
>>>> "If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. "
>>>>
>>>>
>>>> from http://dlang.org/class.html#constructors
>>>>
>>>> the idea is to make sure the base class construction work is done too.
>>>
>>> Is there any way to prevent this behaviour?
>>>
>>> Quickly checked whether Java acts in the same way. Answer is yes.
>>
>> You might be able to swap out the vtbl entry for a stub call it and trick the compiler and swap it back, but...
>
> Urgh...
>
> If you can modify the base class, and you really need it, you can check the dynamic type:
>
> class Base {
> this() {
> if(!cast(Base) this) return;
> // do the initialization
> }
> }
If you're going to do this then you can just use overloading. That will both avoid the runtime check and require the hack to be explicitly enabled in the derived class. IOW:
class B {
this() {
writeln("B.constructor");
foo();
}
struct SkipBCtor {}
this(SkipBCtor) {}
void foo() {
writeln("B.foo");
}
}
class D : B {
this() {
super(SkipBCtor());
writeln("D.constructor");
}
override void foo() {
writeln("D.foo overrides B.foo");
}
}
artur
|
Copyright © 1999-2021 by the D Language Foundation