Constructor Keyword
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.
A natural consequence of Delphi’s rules is that a constructor
can call another constructor of the same class or call an inherited
constructor. The call uses an object reference (namely,
Self
) so the constructor is called as an ordinary
method.
When called using a class reference, Delphi calls the
NewInstance
method to create the instance.
TObject.NewInstance
allocates memory for the new
object and fills that memory with all zeros, but you can override
NewInstance
to create the object in a different
manner.
A common error for new Delphi programmers is to call a constructor using an object-type variable. Rather than creating the object, such a call invariably results in access violations because the object reference is most likely invalid. The compiler can warn you about such errors if you enable compiler warnings in the project options. For example:
var ObjRef: TSomething; begin ObjRef.Create; // wrong ObjRef := TSomething.Create; // right
If you are writing an abstract base class, and the constructor is virtual so you can write a class factory, do not make the constructor abstract. Derived classes should always call an inherited constructor, but if the constructor is abstract, that isn’t possible. If the abstract base class has nothing to do in its constructor, you should supply a constructor that does nothing except call an inherited constructor. For example,
constructor TAbstractBaseClass.Create; begin inherited Create; end;
Always call an inherited constructor. Even if you know that the
inherited constructor does nothing (such as
TObject.Create
), you should call it. The overhead
of calling the inherited constructor is small, but the potential
payback is enormous. Imagine, for example, that a future revision to
the class changes its base class. The new base class constructor
might do something important. Even if the base class remains the
same, the base class constructor might change from doing nothing to
doing something. Changing a base class during code maintenance should
be easy, and should not require a laborious search through all
derived class constructors, checking to see whether they call an
inherited constructor.