为什么TIdTCPClient的Create方法不能override呢? ( 积分: 100 )

  • 主题发起人 主题发起人 lfpsoft
  • 开始时间 开始时间
L

lfpsoft

Unregistered / Unconfirmed
GUEST, unregistred user!
TTCPClientEx = class(TIdTCPClient)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent;); overwride;
destructor Destroy;override;
....
destructor TTCPClientEx.Destroy ;
begin
inherited Destroy;
end;
constructor TTCPClientEx.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//在这里执行初始化操作
end;

应该是父类的声明不是虚函数,所以不能override。
但如果我想在自已的控件在Create时执行一些初始化操作,应该如何设计呢?
 
他的父类Create方法不是虚方法也不是动态方法当然不能Override
 
可以定义自己的构造子:
TTCPClientEx = class(TIdTCPClient)
public
constructor MyCreate(AOwner: TComponent; OtherParams: String);
destructor Destroy;override;


constructor TTCPClientEx.MyCreate(AOwner: TComponent; OtherParams: String);
begin
inherited Create(AOwner);//注意:要使用基类的一些东西时,必须先执行这句,保存基类初始化
//在这里执行其它初始化操作
end;


释构方法不变

--补充:
但是老兄,我看了一个Indy10的源码,TIdTCPClient是从TCompoment继承下来的,是可以override.
而我看了我正在用的Indy9的源码TIdTCPClient的Create构造子是可以override的。

你是哪里的Indy呀? 如果是Delphi6,7自带那个Indy8,9,我劝你不要用了,去下载一个开发快照吧(Indy9好象不再出发布版了,但那个项目组还有人维护它)
http://indy.fulgan.com/

如果要用同名构造子,又不想编译器警告,还可以这样:
constructor Create(AOwner: TComponent); reintroduce;
直接覆盖掉原来的这个构造子定义
 
查DELPHI里的源代码就知道了。
 
我的Delphi版本是2007的.Indy的版本也是Delphi 2007自带的。
无论我是定义为:
constructor Create(AOwner: TComponent); reintroduce;
或者
constructor Create(AOwner: TComponent); reintroduce;overload;
这样在Create里的一些初始化的代码不会运行到的。
不知道是什么原因,详细代码如下。

TTCPClientEx = class(TIdTCPClient)
private
{ Private declarations }
FActiveTime:Integer;
protected
{ Protected declarations }

public
{ Public declarations }
constructor Create(AOwner: TComponent); reintroduce;
destructor Destroy;override;

published
{ Published declarations }
property ActiveTime:Integer read FActiveTime write FActiveTime default 30;
end;

implementation

destructor TTCPClientEx.Destroy ;
begin
inherited Destroy;
end;
constructor TTCPClientEx.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FActiveTime := 30;
end;
 
在Demo里运行:
procedure TMainForm.FormCreate(Sender: TObject);
begin
ShowMessage(IntToStr(TCPClientEx.ActiveTime));
end;
它的结果却还是ActiveTime:=0
 
TCPClientEx的定义是什么?
继承后的组件已经安装到IDE中了么?

你的这种用法,用你开帖的写法就完全对了,其它写法都不适用,包括我提供过的。
你遇到的情况可能是组件安装和使用的问题
 
TIdTCPClient继承自TIdInitializerComponent(很深的继承树),所以,如果你需要初始化某些东西,应该覆盖TIdTCPClient的InitComponent方法,代码如下:

type
TMyIdTCPClient = class(TIdTCPClient)
protedted
procedure InitComponent; override;
end;

procedure TMyIdTCPClient.InitComponent;
begin
inherited InitComponent;
//这里开始初始化你自己的东西
end;
 
zqw0117兄提到的:
TIdTCPClient继承自TIdInitializerComponent(很深的继承树),所以,如果你需要初始化某些东西,应该覆盖TIdTCPClient的InitComponent方法

请恕我眼拙,我觉得这个因为...所以...好象并不是必然的因果关系呀,只要基类的Create方法是virtual,就应该可以一直override下来...
 
delphi7下就可以,没有2007不知道
 
如果把Create声明为overwride,则报错:Cannot override a non-virtual method
控件已正确安装的。
 
szf兄,IdTCPClient的父类(IdBaseComponent)故意将Create改成非virtual的,所以他限制了只能按照他的设计进行初始化的代码撰写方式,所以,必须用override InitComponent方法,而不是Create构造函数来初始化内部数据!这是Indy设计框架的一部分!
 
>>来自:lfpsoft, 时间:2007-12-27 10:21:52, ID:3863108
>>如果把Create声明为overwride,则报错:
>>Cannot override a non-virtual method
>>控件已正确安装的。

楼主请阅读上面我给你的回答,你要初始化任何子类中的数据,必须override InitComponent方法,这是Indy框架限制后唯一允许你初始化数据的地方!请按照要求复写InitComponent方法。
 
问题解决!
 
后退
顶部