Delphi/pascal:使用不同的原型重载构造函数

Dav*_*sky 20 delphi constructor overloading

我正在尝试创建一个子类的TForm

  1. 某些案例的特殊构造函数,以及
  2. 一个默认构造函数,它将保持与当前代码的兼容性.

这是我现在的代码:

interface
  TfrmEndoscopistSearch = class(TForm)
  public
    /// original constructor kept for compatibility
    constructor Create(AOwner : TComponent); overload; override;
    /// additional constructor allows for a caller-defined base data set
    constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); overload;
  end;
Run Code Online (Sandbox Code Playgroud)

它似乎工作,但我总是得到编译器警告:

[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm'
  • 添加"过载"; 在第二个构造函数之后将无法编译."[错误] test.pas(44):"创建"声明与之前的声明不同".
  • 使第二个构造函数的一个类函数编译时没有任何错误或警告,但在运行时死于访问冲突(所有成员变量都是零).

Rob*_*edy 31

有一种非常简单的方法可以避免这种情况.为新构造函数指定一个不同的名称.与其他一些流行语言不同,Delphi 命名了构造函数 ; 你不必称他们为Create.您可以调用新的CreateWithDataset,而不是干扰虚拟的Create构造函数.

TfrmEndoscopistSearch = class(TForm)
  /// original constructor kept for compatibility
  constructor Create(AOwner: TComponent); override;
  /// additional constructor allows for a caller-defined base data set
  constructor CreateWithDataset(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = '');
end;
Run Code Online (Sandbox Code Playgroud)

实际上,除非您以多态方式实例化此类,否则您甚至不需要原始构造函数.你可以像这样申报新的:

TfrmEndoscopistSearch = class(TForm)
  /// additional constructor allows for a caller-defined base data set
  constructor Create(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = ''); reintroduce;
end;
Run Code Online (Sandbox Code Playgroud)

试图直接在TfrmEndoscopistSearch上调用单参数构造函数会产生编译错误.


(以多态方式创建它通常涉及使用Application.CreateForm:

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch);
Run Code Online (Sandbox Code Playgroud)

这总是调用TComponent中引入的单参数虚拟构造函数.除非它是您的主要形式,否则您不需要这样做.我以前写过关于Application.CreateForm的感受.)


Uli*_*rdt 19

尝试reintroduce在第二个之前添加overload,如下所示:

  TfrmEndoscopistSearch = class(TForm)
  public
    /// original constructor kept for compatibility
    constructor Create(AOwner : TComponent); overload; override;
    /// additional constructor allows for a caller-defined base data set
    constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); reintroduce; overload;
  end;
Run Code Online (Sandbox Code Playgroud)

这在Turbo Delphi中编译.我需要public让它编译,因为published方法的重载受到限制.


Rad*_*ina 7

constructor Create(AOwner:Tcomponent;str:string);overload;
... 
constructor TfrmEndoscopistSearch.Create(AOwner: Tcomponent; str: string);
    begin
    inherited Create(AOwner);
    showmessage(str);
    end;
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题