Patrick,

> Let's say I have a class declared as follows
>
> type A =  class(TObject)
>  X: TStringList
>  constructor Create; override;
>  destructor Destroy; override;
> end;
>
> constructor A.Create;
> begin
>        inherited Create;
>       X:=TStringList.Create;
> end;
>
> destructor A.Destroy;
> begin
>         X.Free;
>         inherited Destroy;
> end;

> Now I know that the default constructor for TObject will not
> allocate space
> to X so it seems logical to override the default constructor
> with my own,
> and call the inherited constructor within that. Ditto the
> destructor to
> deallocate X.
>
> Except that the keyword override next to my declared constructor and
> destructor causes an error message about overriding a static
> method. So I
> leave out the override keyword and it compiles.
>
> But what is the difference?

There are many ways to achieve this:

1.  Instead of the constructor / destructor, try overriding the
AfterConstruction / BeforeDestruction procedures.  This way is more
compatible with C++ Builder if you need to call virtual methods from your
constructor.  (C++ does not support calling virtual methods from the
constructor.)  Furthermore, if you use this method, you don't need to worry
that TComponent, TCollection, TCollectionItem, TPersistent all have
different constructors!

2.  TObject declares a static constructor, which cannot be overriden.  If
you declare a new constructor, you will *HIDE* TObject's declaration.  This
is because you actually call it directly, as in y := A.Create;.

Don't confuse this with virtual constructors:

program Test;

type
  TA = class
  public
    constructor Create; Virtual;
  end;

  TAClass = class of TA;

  TB = class (TA)
  public
    constructor Create; Override;
  end;

  constructor TA.Create;
  begin
    Inherited;  // Calls TObject's constructor
    WriteLn ('constructor TA.Create');
  end;

  constructor TB.Create;
  begin
    Inherited;  // Calls TA's constructor
    WriteLn ('constructor TB.Create');
  end;

var
  AClass: TAClass;
  x, y: TA;

begin
  AClass := TA;
  x := AClass.Create;   // Calls TA's constructor
  AClass := TB;
  y := AClass.Create;   // Calls TB's constructor
end.


This will result in the following in the console:

constructor TA.Create
constructor TB.Create


Note that if TA's constructor is not virtual, and hence TB's constructor
does not override it, the second call to the constructor results in a call
to TA's constructor.  So, if instead you declare your objects as:

type
  TA = class
  public
    constructor Create;
  end;

  TAClass = class of TA;

  TB = class (TA)
  public
    constructor Create;
  end;

you will get the following:

constructor TA.Create
constructor TA.Create


Try it out.


Regards,
Dennis.

---------------------------------------------------------------------------
    New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
                  Website: http://www.delphi.org.nz

Reply via email to