www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Asserting that a base constructor is always called

reply Tim <t.oliver windowslive.com> writes:
I have a base class GameObject:

/// Base class of most objects in the game
class GameObject{
     this(){
         world[layer] = this;
     }

     abstract void update(){}

     void draw(){}
}

I want to make sure that whenever a class inherits from this, the 
base constructor is always called. Either that or have an 
assertion that gives an error if it isn't called.

Thanks
May 23 2020
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 5/23/20 3:04 PM, Tim wrote:
 I have a base class GameObject:
=20
 /// Base class of most objects in the game
 class GameObject{
  =C2=A0=C2=A0=C2=A0 this(){
  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 world[layer] =3D this;
  =C2=A0=C2=A0=C2=A0 }
=20
  =C2=A0=C2=A0=C2=A0 abstract void update(){}
=20
  =C2=A0=C2=A0=C2=A0 void draw(){}
 }
=20
 I want to make sure that whenever a class inherits from this, the base =
 constructor is always called. Either that or have an assertion that=20
 gives an error if it isn't called.
=20
 Thanks
Is it not already called? I tried the following and it seems to work: import std.stdio; GameObject[1] world; enum layer =3D 0; /// Base class of most objects in the game class GameObject{ this(){ world[layer] =3D this; writeln("called"); } abstract void update(){} void draw(){} } class A : GameObject { this(int i) { writeln(__FUNCTION__); } override void update() { } } void main() { auto a =3D new A(42); } Ali
May 23 2020
parent reply Tim <t.oliver windowslive.com> writes:
On Saturday, 23 May 2020 at 22:15:49 UTC, Ali Çehreli wrote:
 Is it not already called? I tried the following and it seems to 
 work:

 import std.stdio;

 GameObject[1] world;
 enum layer = 0;

 /// Base class of most objects in the game
 class GameObject{
   this(){
     world[layer] = this;
     writeln("called");
   }

   abstract void update(){}

   void draw(){}
 }

 class A : GameObject {
   this(int i) {
     writeln(__FUNCTION__);
   }

   override void update() {
   }
 }

 void main() {
   auto a = new A(42);
 }

 Ali
It is but I want to make sure for other cases in the future where I create a new class that inherits from GameObject. This was I can avoid future bugs by ensure that all classes in the future that inherit from GameObject, call it's constructor
May 23 2020
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, May 23, 2020 4:43:04 PM MDT Tim via Digitalmars-d-learn wrote:
 It is but I want to make sure for other cases in the future where
 I create a new class that inherits from GameObject. This was I
 can avoid future bugs by ensure that all classes in the future
 that inherit from GameObject, call it's constructor
The base class constructor will _always_ be called. There's no need to worry about it. Even if you hadn't declared one, the compiler will provide a default constructor, because classes have to have a constructor. And if you had declared a constructor in your base class but no default constructor, then you'd get a compile-time error if your derived class' constructor didn't explicitly call it. - Jonathan M Davis
May 23 2020
parent reply Tim <t.oliver windowslive.com> writes:
On Sunday, 24 May 2020 at 00:51:17 UTC, Jonathan M Davis wrote:
 On Saturday, May 23, 2020 4:43:04 PM MDT Tim via 
 Digitalmars-d-learn wrote:
 It is but I want to make sure for other cases in the future 
 where I create a new class that inherits from GameObject. This 
 was I can avoid future bugs by ensure that all classes in the 
 future that inherit from GameObject, call it's constructor
The base class constructor will _always_ be called. There's no need to worry about it. Even if you hadn't declared one, the compiler will provide a default constructor, because classes have to have a constructor. And if you had declared a constructor in your base class but no default constructor, then you'd get a compile-time error if your derived class' constructor didn't explicitly call it. - Jonathan M Davis
Oh right. I mean it makes sense but I got confused when super() is valid syntax. Why would you need to call the super constructor when it's called automatically?
May 23 2020
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 24 May 2020 at 06:38:46 UTC, Tim wrote:
 Oh right. I mean it makes sense but I got confused when super() 
 is valid syntax. Why would you need to call the super 
 constructor when it's called automatically?
A base class with a constructor that has no args will automatically get called at the start of a child class if it is not explicitly called. You can call it yourself anywhere in an always executed branch of the constructor. As for why, if you wanted to do some logging before the base constructor was called. You need to call the base class's constructor explicitly when it has arguments and there is no default constructor in the base class. This must be done in an always executed branch. This must be called or the compiler will issue an error.
May 24 2020
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, May 24, 2020 12:38:46 AM MDT Tim via Digitalmars-d-learn wrote:
 Oh right. I mean it makes sense but I got confused when super()
 is valid syntax. Why would you need to call the super constructor
 when it's called automatically?
1. If you wanted to run any code before calling the base class constructor. e.g. depending on the arguments to the derived class constructor, you could call one base constructor, or you could call a different base class constructor. You could even have the base class constructor call a virtual function, and what that virtual function did depended on something you had set in the derived class prior to calling the base class constructor (since unlike C++, it's safe to call virtual functions from within constructors). 2. If the base class constructor is not a default constructor, then you have to explicitly call it, because it has to be passed arguments. - Jonathan M Davis
May 24 2020