gw_logo_08.gif (1982 bytes) 
Last edit: 05-03-17 Graham Wideman

Delphi

Notes on Delphi Constructors and Destructors
Article created: 98-11-01

The implications of making constructors and destructors virtual or not are not necessarily obvious. First, it's helpful to look at the declaration of TObject, from which all other objects descend, even if they don't say so.

Type
  TObject = class
    constructor Create;
    [...]
    destructor Destroy; virtual;
  end;
[...]
constructor TObject.Create;
begin
end;
destructor TObject.Destroy;
begin
end;

Notes:

  1. TObject.Create and TObject.Destroy both do nothing.
  2. TAnyObject.Create is preceded by allocation of space and zeroing of fields. (AnyInstance.Create is not so treated -- it merely executes AnyInstance.Create).  In other words, it is NOT the calling of TObject.Create that causes the allocation and zeroing.  Likewise in reverse for Destroy.
  3. Hence, if you are inheriting from TObject (ie: defining a new base class that doesn't inherit from anything other than TObject.) then you are free to call or not call inherited Create and Destroy.

Create

Ancestor is. . .
TObject.Create
(static)
TSomeObject.Create; static; TSomeObject.Create; virtual/override;
Descendant Create
Same Args static OK, but precludes descendant override. If called by class reference, then wrong constructor called? If called by class reference, then wrong constructor called ?
virtual Defines new constructor Defines new constructor ?
override Error Error Sensible
Different Args static
virtual Defines new constructor Defines new constructor Defines new constructor, Sensible
override Error Error Error
Calling inherited Create no effect since  TObject.Create doesn't do anything. Sensible Sensible

Destroy

Ancestor is. . .
TObject.Destroy; virtual; TSomeObject.Destroy; override; TSomeObject.Destroy; Static
Descendant Destroy
static Bad because if object is owned by a list (which will destroy it) via an ancestor-type pointer, wrong Destroy will be called. Bad ancestor.
virtual Bad Bad (or error?)
override Good Good
Calling inherited Destroy no effect since TObject.Destroy doesn't do anything. Usually advisable Bad ancestor.

Go to:  gw_logo_08.gif (1982 bytes)