2013-06-03 75 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流式系统调用的构造函数。 –