【问题标题】:SerialForms.pas(17): W1010 Method 'Create' hides virtual method of base type 'TComponent'SerialForms.pas(17):W1010 方法“创建”隐藏基本类型“TComponent”的虚拟方法
【发布时间】:2012-12-19 14:32:01
【问题描述】:

我创建了一个类

  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'

在不丢失应用程序功能的情况下消除此警告需要做什么?

【问题讨论】:

  • 从 .dfm 文件创建表单时,它会调用 TComponent 中引入的虚拟构造函数。当表单来自 .dfm 时,您的构造函数将永远不会被调用。如果您的构造函数创建了任何对象,那么您就会遇到问题。你的设计可能是错误的。
  • 隐藏继承的 TComponent 虚拟 ctor 是个坏主意,如果您想让其他 ctor 使用不同的名称,例如 CreatePos
  • @user 你现在问了很多问题。这很好。但也许你可以考虑投票选出好的答案。
  • BTW 你知道在最近的 Delphi 版本中,你可以对错误/警告/提示消息执行 Ctrl-F1 以获取更多信息吗?值得注意的是,这个错误的帮助给出了具体的原因和解决方案

标签: delphi build constructor warnings delphi-xe2


【解决方案1】:

使用reintroduce 保留字表示您想要在您的类中有意隐藏基类构造函数的编译器:

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

这样,不会显示警告。

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

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

如果是这种情况,您的组件必须支持“未配置”,或者在此 universal 构造函数中为其属性设置默认值。

您可以提供更多具有不同名称的构造函数,以便您在运行时根据不同属性的代码传递值创建实例,以方便您使用。

【讨论】:

  • 重新引入会破坏多态性。这意味着您不能再使用元类(TxxxClass = Tyyy 的类)来实例化您的 TComponent 后代,因为它的 Create 不会被调用。另见:stackoverflow.com/questions/53806/…
  • @Marjan 您仍然可以使用元类和虚拟构造函数创建实例。恕我直言,能够隐藏虚拟构造函数只是您手头的一个工具,有时可能会派上用场。我不记得我什么时候用过,或者我用过一次。我不反对,但看起来我也不会使用它。
  • 是的,你可以,但我真的不认为隐藏你可以访问的东西有什么用。我更喜欢为这种首先调用标准构造函数(没有继承)的东西创建一个显式命名的构造函数(即CreateWith)。
【解决方案2】:

如果您为构造函数使用不同的名称,可能会更好 - 并且更具可读性,例如

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2017-10-27
    • 1970-01-01
    • 2014-02-09
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多