www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - C++ base constructor call vs. D's

reply Just Dave <abcdef 1234.com> writes:
I was reading the C++ to D page, and came across this little bit 
about when to call the base class constructor:

"It's superior to C++ in that the base constructor call can be 
flexibly placed anywhere in the derived constructor."

Isn't there some inherent danger of not calling the base 
constructor first? Wouldn't C++'s method actually be equal in the 
effect that you could just overwrite whatever value the base 
class set in the derived class?
Oct 02 2019
next sibling parent kinke <noone nowhere.com> writes:
On Wednesday, 2 October 2019 at 17:22:40 UTC, Just Dave wrote:
 I was reading the C++ to D page, and came across this little 
 bit about when to call the base class constructor:


 Isn't there some inherent danger of not calling the base 
 constructor first?
The object's fields are pre-initialized before invoking the constructor, and not undefined as in C++, so probably not really dangerous.
 "It's superior to C++ in that the base constructor call can be 
 flexibly placed anywhere in the derived constructor."
That formulation is s bit suboptimal, as the emphasis should be on '*can* be flexibly placed anywhere' - if you don't specify an explicit `super()` call, it's implicitly inserted at the beginning of the derived ctor, so a base ctor is always invoked at some time when constructing a derived object. I don't think there are lots of use cases for deferring the super call, but it might be useful for logging purposes and such.
Oct 02 2019
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, October 2, 2019 11:22:40 AM MDT Just Dave via Digitalmars-d-
learn wrote:
 I was reading the C++ to D page, and came across this little bit
 about when to call the base class constructor:

 "It's superior to C++ in that the base constructor call can be
 flexibly placed anywhere in the derived constructor."

 Isn't there some inherent danger of not calling the base
 constructor first? Wouldn't C++'s method actually be equal in the
 effect that you could just overwrite whatever value the base
 class set in the derived class?
The key difference in D has to do with init values. With a struct, the values that its members are directly initialized with create its init value. So, struct S { string s = "hello"; int i; int j = 42; } results in assert(S.init == S(s, 0, 42)); For classes, because the type system always treats them as references, the init value is null. So class C { string s = "hello"; int i; int j = 42; } results in assert(C.init is null); However, the class still has the equivalent of the struct's init value - you just can't access it directly, and it's not used for default initialization, just in construction. So, before a class' constructor is run, its memory is initialized with that hidden init value, meaning that you don't have garbage when you enter the constructor, and the class is already fully formed in terms of its type and virtual table before any constructors are called, whereas in C++, if you're in a base class constructor, that class object is not yet the derived class type. So, it's actually possible and safe to call virtual functions from within a class constructor in D, whereas it isn't in C++. So, this example prints "D" class C { string foo() { return "C"; } this() { import std.stdio; writeln(foo()); } } class D : C { override string foo() { return "D"; } } void main() { auto d = new D; } whereas C++ equivalent would likely blow up in your face. - Jonathan M Davis
Oct 02 2019