I just wanted to ask a simple question - I have a class derived from TLabel as follows:
TMyLabel = class (TLabel)
...
constructor Create(AOwner: TComponent); override;
end;
constructor TMyLabel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{ some code }
end;
Now, Delphi lets me compile both versions with and without the override. Could you explain what the differences are? Other than being unable to request my own parameters in Create()
when overridden. Thanks
Edit: What I mean is - what is the difference between a virtual
and a nonvirtual base-descendant constructors? I can always call the inherited constructor by inherited Create()
, so what's the point?
Virtual constructors allow for polymorphic instantiation of objects. The classic example of this is Delphi's .dfm streaming mechanism.
The code that reads .dfm files and instantiates forms does not know at compile time which classes to use. The decision is postponed until runtime when it can be made correctly, i.e. when the .dfm file is read. Moreover, you can get the .dfm file mechanism to create custom components that are not part of the VCL and so this .dfm mechanism must be capable of correctly instantiating classes that are not part of the VCL.
The constructor for TComponent
is declared like this:
constructor Create(AOwner: TComponent); virtual;
For a component to take part in this mechanism it must declare its constructor with the override
directive.
The other key to the process is class references. For example
type
TComponentClass = class of TComponent;
The code that creates components when reading .dfm files, roughly, looks like this:
var
ComponentClass: TComponentClass;
Component, Owner: TComponent;
....
ComponentClass = FindComponentClass(ReadComponentClassName);
Component := ComponentClass.Create(Owner);
Now, if the mechanism did not use virtual constructors then the constructor that would be called would be TComponent.Create
. And so your constructor, TMyLabel.Create
would never be called.
This is why you must include the override directive on your constructors when deriving from TComponent
.
Well, if I remember Delphi correctly (that was a while ago, though it was good time :) ) when constructor is overriden you'll be able to call it via class references (see this spec as example).