2013-06-03 74 views
0

我新的德爾福,我在Delphi 6創建一個組件,但我不能讓構造函數運行:德爾福自定義構造函數永遠不會運行

unit MyComms1; 
... 
type 
    TMyComms = class(TComponent) 
    public 
     constructor MyConstructor; 
    end; 
implementation 

constructor TMyComms.MyConstructor; 
begin 
    inherited; 
    ShowMessage('got here'); 
end; 

不要緊什麼構造函數被調用,但是這個代碼根本不運行構造函數。

編輯

由請求,這裏是TMyComms類是如何初始化(這個碼是在一個不同的文件名爲TestComms.pas):

unit TestComms; 

interface 

uses MyComms1, ... 

type 
    TForm1 = class(TForm) 
    MyCommsHandle = TMyComms; 
    ... 
    procedure BtnClick(Sender: TObject); 
    private 
    public 
    end; 
var 
    Form1: TForm1; 

implementation 

procedure TForm1.BtnClick(Sender: TObject); 
begin 
    MyCommsHandle.AnotherMyCommsProcedure; 
end; 

編輯2

閱讀一些看起來像構造函數的答案必須在delphi中手動調用。它是否正確?如果是這樣,那麼這肯定是我的主要錯誤 - 我習慣於在__construct函數被自動調用,每當一個類被分配到一個句柄。

+3

,只要你喜歡,所以我不知道是否和如何PHP解決了,但據我所知,'Java','C#','C你可以有許多構造++',...,'Delphi' * *全部**需要正確的構造函數被手動調用。 –

+0

這裏最大的問題是虛擬構造函數。 @mull你有興趣瞭解這個問題。 –

+0

您必須更改您在PHP中獲得的許多*習慣。我想,這將是明智的*不要假設,該語言的結構與PHP類似,因爲通常它們不會。 – Spook

回答

2

您的代碼不遵循Delphi命名指南 - 構造函數應該命名爲Create

由於您沒有發佈實際調用ctor的代碼,我想,您可能根本沒有調用它。嘗試將一個按鈕添加到您的窗體,雙擊它,並添加以下代碼:

procedure TForm1.Button1Click(Sender : TObject) 

var comms : TMyComms; 

begin 
    comms := TMyComms.MyConstructor; 
    comms.Free; 
end; 

順便說一句,如果你從TComponent派生,你應該重寫構造函數的參數 - 否則繼承的方法可能無法正常工作。

interface 

type TMyComms = class(TComponent) 
    private 
    protected 
    public 
    constructor Create(AOwner : TComponent); override; 
    end; 

implementation 

constructor TMyComms.Create(AOwner : TComponent) 
begin 
    inherited Create(AOwner); 
    // Your stuff 
end; 

// Somewhere in code 
var comms : TMyComms; 

begin 
comms := TMyComms.Create(nil); 
end; 
+0

歡呼聲。你是否說我可以根據你的第二個代碼片段將'MyConstructor'重命名爲'Create'並且忽略第一個代碼片段?如果是的話不幸的是我的構造函數仍然不能運行。 – mulllhausen

+0

ctor *可能*被命名爲MyConstructor,但是一般的Delphi命名準則說ctors *應該*命名爲Create。在被叫或不被叫的情況下無關緊要。但是,你沒有告訴我們,你怎樣試圖調用ctor(它應該在創建類時被調用),所以在你發佈一些代碼之前(在這種情況下請編輯你的問題)我無法幫助你。 – Spook

+0

啊謝謝澄清。我將發佈如何初始化'TMyComms'類的代碼 – mulllhausen

3

很可能你沒有調用TMyComms.MyConstructor來測試你的不尋常的被調用和使用的構造函數。標有// **的方式將是最常用的方式。

type 
    TMyComms = class(TComponent) 
    public 
     constructor MyConstructor; 
    // the usual override; 
    // constructor Create(Owner:TComponent);override; // **  
     constructor Create(AOwner:TComponent);overload; override; 
     constructor Create(AOwner:TComponent;AnOtherParameter:Integer);overload;  
    end; 

constructor TMyComms.Create(AOwner: TComponent); 
begin 
    inherited ; 
    ShowMessage('got here Create'); 
end; 

constructor TMyComms.Create(AOwner: TComponent; AnOtherParameter: Integer); 
begin 
    inherited Create(AOwner); 
    ShowMessage(Format('got here Create with new parametere %d',[AnOtherParameter])); 
end; 

constructor TMyComms.MyConstructor; 
begin 
    inherited Create(nil); 
    ShowMessage('got here MyConstructor'); 
end; 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
    TMyComms.MyConstructor.Free; 
    TMyComms.Create(self).Free; 
    TMyComms.Create(self,1234).Free; 

end; 
+0

需要將'Create(AOwner:TComponent)'構造函數聲明爲'override'。你也可以'重載'它。 –

2

您的自定義構造函數未被調用,因爲您沒有調用它。

MyComm := TMyComms.MyConstructor; 

但是,您在代碼中也有錯誤。因爲沒有派生的構造函數,所以可以用簡單的inherited繼承。

type 
    TMyComms = class(TComponent) 
    public 
     constructor MyConstructor; 
    end; 
implementation 

constructor TMyComms.MyConstructor; 
begin 
    inherited Create(nil); // ! 
    ShowMessage('got here'); 
end; 

您可以使用簡單的inherited如果您的自定義構造函數中使用相同的名稱和參數,從現有的構造函數。

type 
    TMyComms = class(TComponent) 
    public 
     constructor Create(AOwner : TComponent); override; 
    end; 
implementation 

constructor TMyComms.Create(AOwner : TComponent); 
begin 
    inherited; // <- everything is fine 
    ShowMessage('got here'); 
end; 
+0

這是我的理解,當類被分配到句柄時,會自動調用構造函數。你是說我必須專門調用構造函數過程嗎? – mulllhausen

+2

是的,在Delphi中你必須通過調用類似'LInstanceVar:= TMyClass.Create;'的構造函數來創建一個實例。 –

+0

如果你希望組件是DFM流式的,那麼你必須重寫虛擬的'TComponent.Create(AOwner:TComponent)'構造函數,因爲它是DFM流式系統調用的構造函數。 –