重写和非重写构造函数
我只想问一个简单的问题-我有一个从TLabel派生的类,如下所示:
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;
现在,Delphi允许我编译带有和不带有 override 的两个版本.你能解释一下有什么区别吗? 覆盖时无法在Create()
中请求我自己的参数.谢谢
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
我的意思是-virtual
和非虚拟后代构造函数之间有什么区别?我总是可以通过inherited Create()
调用继承的构造函数,那有什么用呢?
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?
虚拟构造函数允许对象的多态实例化.经典的例子是Delphi的.dfm流机制.
Virtual constructors allow for polymorphic instantiation of objects. The classic example of this is Delphi's .dfm streaming mechanism.
读取.dfm文件并实例化表单的代码在编译时不知道要使用哪些类.该决定被推迟到运行时才能正确做出,即当读取.dfm文件时.此外,您可以获得.dfm文件机制来创建不属于VCL的自定义组件,因此,该.dfm机制必须能够正确实例化不属于VCL的类.
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.
TComponent
的构造函数声明如下:
The constructor for TComponent
is declared like this:
constructor Create(AOwner: TComponent); virtual;
要使组件参与此机制,必须使用override
指令声明其构造函数.
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;
大致上,在读取.dfm文件时创建组件的代码如下:
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);
现在,如果该机制未使用虚拟构造函数,则将被调用的构造函数为TComponent.Create
.因此,您的构造函数TMyLabel.Create
将永远不会被调用.
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.
这就是为什么从TComponent
派生时必须在构造函数上包括override指令的原因.
This is why you must include the override directive on your constructors when deriving from TComponent
.