SerialForms.pas(17): W1010方法“Create”隐藏了基类型“TComponent”的虚拟方法

4
我创建了一个类。
  FormInfo = class (TComponent)
  private
    FLeftValue : Integer;
    FTopValue : Integer;
    FHeightValue : Integer;
    FWidthValue : Integer;
  public
    constructor Create(
      AOwner : TComponent;
      leftvalue : integer;
      topvalue : integer;
      heightvalue : integer;
      widthvalue : integer);
  protected
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
    function  GetChildOwner: TComponent; override;
    //procedure SetParentComponent(Value : TComponent); override;
  published
    property LeftValue : Integer read FLeftValue write FLeftValue;
    property TopValue : Integer read FTopValue write FTopValue;
    property HeightValue : Integer read FHeightValue write FHeightValue;
    property WidthValue : Integer read FWidthValue write FWidthValue;
  end;

该方法用于进一步的表单序列化。Create 方法的实现如下:

constructor FormInfo.Create(AOwner: TComponent; leftvalue, topvalue, heightvalue,
  widthvalue: integer);
begin
  inherited Create(AOwner);

  FLeftValue := leftvalue;
  FTopValue := topvalue;
  FHeightValue := heightvalue;
  FWidthValue := widthvalue;
end;

由于装配,我收到了警告。
[dcc32 Warning] SerialForms.pas(17): W1010 Method 'Create' hides virtual method of base type 'TComponent'

如何在不影响应用程序功能的情况下消除此警告?


1
请参见http://docwiki.embarcadero.com/RADStudio/XE3/en/W1010_Method_%27%25s%27_hides_virtual_method_of_base_type_%27%25s%27_%28Delphi%29。 - ain
2
当你的窗体是从 .dfm 文件创建时,它会调用 TComponent 中引入的虚拟构造函数。当窗体从 .dfm 文件中加载时,你的构造函数不会被调用。如果你的构造函数创建了任何对象,那么就会出现问题。你的设计可能是错误的。 - David Heffernan
2
隐藏继承的 TComponent 虚拟构造函数是一个不好的主意,如果你想要有额外的构造函数,请使用另一个名称,比如 CreatePos - kludg
1
@user 你已经提了很多问题了,这没问题。但或许你可以考虑为好的答案投票。 - David Heffernan
顺便问一下,您知道在更近的Delphi版本中,您可以在错误/警告/提示消息上按Ctrl-F1以获取更多信息吗?值得注意的是,此错误的帮助提供了具体的原因和解决方案。 - Jan Doggen
2个回答

8

使用reintroduce保留字,告诉编译器你想在类中有意隐藏基类构造函数:

TMyClass = class (TComponent)
public
  constructor Create(AOwner: TComponent; MyParam: Integer; Other: Boolean); reintroduce;

这样,就不会显示任何警告。

话虽如此,您必须重新考虑隐藏TComponent.Create构造函数。这是一个坏主意,因为Delphi在设计时将调用默认的TComponent.Constructor来运行时创建组件实例,当添加到表单/数据模块时。

TComponent使构造函数成为虚拟函数,以允许您在该过程中执行自定义代码,但您必须坚持使用Create方法仅传递owner,并让流式处理机制处理创建完成后的属性存储值。

如果需要,您的组件必须支持“未配置”,或在此“通用”构造函数中设置其属性的默认值。

您可以提供更多构造函数,使用不同的名称,以便于您从代码中运行时创建实例并传递不同属性的值。


重新引入断点多态性。这意味着您不能再使用元类(TxxxClass = Tyyy的类)来实例化TComponent派生类,因为它的Create方法不会被调用。参见:https://dev59.com/dXVD5IYBdhLWcg3wNIvc - Marjan Venema
@Marjan 你仍然可以使用元类和虚构造函数来创建实例。在我看来,隐藏虚构造函数的能力只是一个可用的工具,在某些时候可能会有用。我不记得我何时使用过它或者是否曾经使用过它。我不反对它,但似乎我也没有使用它。 - jachguate
是的,你可以这样做,但我真的看不出隐藏可以访问的东西有什么用。我更喜欢为这种情况创建一个明确命名的构造函数(例如CreateWith),该构造函数首先调用标准构造函数(不包括继承)。 - Marjan Venema

2

如果你使用一个不同的名称来命名你的构造函数,比如

可能会更好并且更易读。

constructor FormInfo.CreateWithSize(AOwner: TComponent; leftvalue, topvalue, heightvalue, widthvalue: integer);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接