Delphi: Default parameterless constructor

A weird consequence of Delphi’s OOP behavior is how constructors are handled, and in particular how the default parameterless constructor is handled.

Consider the following example:
[Delphi]
type
TMyClass = class
end;

var
Obj: TMyClass;

begin
Obj := TMyClass.Create();
Obj.Free();
end.
[/Delphi]
This code will actually compile and run. This happens because Create() constructor is inherited from TObject base class. So far, so good (actually it’s not that good, but at least we know what happens).

Now let’s define a parameterless private constructor (hoping to hide it like in other OOP languages):
[Delphi]
type
TMyClass = class
private
constructor Create();
end;

{ TMyClass }
constructor TMyClass.Create;
begin
end;

var
Obj: TMyClass;

begin
Obj := TMyClass.Create();
Obj.Free();
end.
[/Delphi]
This will again compile and run! But now, the actual TMyClass.Create() constructor will be called even if it’s private. It seems you cannot make a private version of the default constructor … Bad!

Third try: Let’s define a constructor with parameters and see what happens then:
[Delphi]
type
TMyClass = class
public
constructor Create(const AParameter: Integer);
end;

{ TMyClass }
constructor TMyClass.Create(const AParameter: Integer);
begin
end;

var
Obj: TMyClass;

begin
Obj := TMyClass.Create();
Obj.Free();
end.
[/Delphi]
OK, now we have a compilation error: “Not enough actual parameters” for TMyClass.Create() call. Well, that’s not exactly what we wanted, but it will do for now: we got rid of the default constructor!

And the final try, suppose you want a class that has more than one constructor:
[Delphi]
type
TMyClass = class
public
constructor Create(const AParameter: Integer); overload;
constructor Create(const AParameter: String); overload;
end;

{ TMyClass }
constructor TMyClass.Create(const AParameter: Integer);
begin
end;

constructor TMyClass.Create(const AParameter: String);
begin
end;

var
Obj: TMyClass;

begin
Obj := TMyClass.Create();
Obj.Free();
end.
[/Delphi]
Bad! — it compiles again.

It seems that no matter what I do, I can’t get rid of the default constructor! The only reasonable thing I can do is define a default constructor that just raises an Exception if it’s called.

Coming up next: Generic class restriction: “constructor”.