2009-11-18 66 views
14

我試圖創建一個子類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; 

看來工作,但我總是得到編譯器警告:

 
[Warning] test.pas(44): Method 'Create' hides virtual method of base type 'TCustomForm' 
  • 加入 「超載」;在第二個構造函數不會編譯之後。 「[錯誤] test.pas(44):」創建聲明與以前的聲明不同「。
  • 使第二個構造函數成爲一個類函數,沒有任何錯誤或警告,但在運行時死於訪問衝突(所有成員變量均爲零)。

回答

16

嘗試第二overload之前添加reintroduce,像這樣:

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; 

這將編譯在渦輪德爾福。我需要public來編譯它,因爲published方法的重載受到限制。

+0

bango! 「reintroduce」關鍵字正是需要的。最初的構造函數也是需要的,因爲它將數據集設置爲正確的默認值。 – 2009-11-20 13:56:13

26

有一個非常簡單的方法來避免這種情況。 給你的新構造函數一個不同的名字。與其他一些流行語言不同,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; 

事實上,除非您以多態方式實例化此類,否則您甚至不需要原始構造函數。你可以宣佈新的一個是這樣的:

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

嘗試調用直接TfrmEndoscopistSearch的一個參數的構造函數會產生編譯錯誤。


(創建它多態通常涉及使用Application.CreateForm:

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch); 

總是調用TComponent推出的一個參數的虛構造除非它是你的主要形式,你不需要要做到這一點,我以前也寫過關於my feelings on Application.CreateForm

+0

這可能是最合適的解決方案,但它不是問題的答案。練習的一部分是解決問題,而不必更改已經使用create()的一種或另一種形式的其他10個左右的文件。我將這個表格合併爲兩個不同的項目,並且不想分叉。 – 2009-11-20 13:49:40

6
constructor Create(AOwner:Tcomponent;str:string);overload; 
... 
constructor TfrmEndoscopistSearch.Create(AOwner: Tcomponent; str: string); 
    begin 
    inherited Create(AOwner); 
    showmessage(str); 
    end; 

這應該做的伎倆