www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why is the constructor of B called?

reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
[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.
Sep 23 2015
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Sep 23 2015
parent reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
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.
Sep 23 2015
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Sep 23 2015
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
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
Sep 23 2015
prev sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
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...
Sep 23 2015
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
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 } }
Sep 24 2015
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
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.
Sep 24 2015
prev sibling parent Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
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
Sep 24 2015