Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi - Ensure a class constructor is called

This is probably a simple question, but i would like to know how to ensure a class' constructor is called.

If i have the following code:

type TMyObject = class(TObject)
  public
     constructor Create;override;
end;

implementation 

constructor TMyObject.Create;override;
begin
  inherited;
  //do other instantiation
end;

Delphi does not allow this - 'Cannot override a static method'.

What i would like to do is ensure that the object is created using my custom Create constructor AND prohibiting calling the ancestors Create constructor.

My current solution to the problem is to define a uniquely signatured Create constructor like so:

constructor Create(aName : String);overload;

but the programmer could potentially call the ancestors Create() method.

like image 322
Simon Avatar asked Jul 11 '11 05:07

Simon


People also ask

What is a constructor in Delphi?

A constructor is a special kind of method. If you call a constructor using a class reference, Delphi creates a new instance of that class, initializes the instance, and then calls the constructor proper. If you call a constructor using an object reference, Delphi calls the constructor as an ordinary method.

How do you call a class constructor?

Calling a Constructor You call a constructor when you create a new instance of the class containing the constructor. Here is a Java constructor call example: MyClass myClassVar = new MyClass(); This example invokes (calls) the no-argument constructor for MyClass as defined earlier in this text.

What is a class constructor?

A constructor of a class is a special method that gets called when a class is instantiated using the NEW function. A constructor for a class has the same name as the class name. Unlike ordinary methods, a constructor definition is identified by the CONSTRUCTOR statement.

Can you call class methods in the constructor?

Yes, as mentioned we can call all the members of a class (methods, variables, and constructors) from instance methods or, constructors.


1 Answers

You simply re-introduce a constructor with the ancestor's name. Once you do that, there's no way for the user to create a TMyObject calling the constructor introduced in TObject. If you use code like this:

TMyObject = class
public
  constructor Create;
end;

constructor TMyObject.Create;
begin
  // I am not calling the inherited constructor because
  // I do not want to.
end;

You don't use the override modifier on TMyObject.Create because the ancestor's constructor is not virtual.

Using this scheme it is impossible for the user to create your TMyObject using a constructor introduced in an ancestor. In this case, the ancestor is TObject, and the only constructor it has is TObject.Create. If the user writes this code:

X := TMyObject.Create;

it's quite obvious, TMyObject's constructor would be called, not the one introduced in TObject.


If you're afraid users would jump through hoops in order to create your class using ancestor's constructor, you can do your stuff from the AfterConstruction method. That's a virtual method, so it gets called even if your object is created using a class reference of an ancestor's type:

TMyObject = class
public
  procedure AfterConstruction;override;
end;
like image 150
Cosmin Prund Avatar answered Sep 22 '22 17:09

Cosmin Prund