全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2725
推到 Plurk!
推到 Facebook!

类方法指针和事件

 
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2006-08-04 13:15:57 IP:219.133.xxx.xxx 未訂閱
Delphi 里的事件,实际上是一个类的方法的指针。比如:

TSayHello = procedure(S:string) of object;

TObj_A = class
private
FSayHello: TSayHello;
pbulic
procedure DoSayHello;

property SayHello: TSayHello read FSayHello write FSayHello;
end;

procedure TObj_A.DoSayHello;
begin
if Assigned(FSayHello) then FSayHello('Hi, how are you'); //<----这里,调用了某个其它类的一个方法!
end;


但是,如果有某个事件发生的时候,要调用多个类的相同方法,该怎么办?写成:

TObj_A = class
private
FSayHello: TSayHello;
FSayHello1: TSayHello;
FSayHello2: TSayHello;

....
pbulic
procedure DoSayHello;

property SayHello: TSayHello read FSayHello write FSayHello;
end;

这样写当然可以。但如果不知道应该有多少个外部的类需要调用这个方法(事件)来通知,该怎么办?

我们自然可以想到是用一个 List 来记录一系列的 FSayHello: TSayHello;

不过, List 里面记录的是 Pointer,而一个 FSayHello: TSayHello; 却是类的方法。如果简单地 @FSayHello 这样取指针,取道的指针是不正确的。

一个方法,包括两个指针,而不是一个指针!按照 Delphi 在 System 里的定义:

Unit

System

Delphi syntax:

type
TMethod = record
Code, Data: Pointer;
end;

一个方法,即一个 TMethod 包含两个指针!

如果我们要把一个方法的指针放入到 List 里,并且想之后再从 List 里取出这个方法的指针来调用这个方法,那么,就要把方法的指针保存到 TMethod 里去。以下代码演示了如何做,我自己试验过,以下代码是可以运行的。

因此,要用一个 TMethod
类型的指针来存放方法的地址。以下代码测试通过,可以把方法地址保存到
TList 里,并且可以拿出来调用:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls;

type
TMyMethod = procedure(S:string) of object;

PMethod = ^TMethod;

TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FList:TList;
procedure SayHello(S:string);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.SayHello(S: string);
begin
Memo1.Lines.Add('Hello,' S);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FList := TList.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FList.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
APointer:PMethod;
begin
New(APointer);
APointer^.Code:=Addr(TForm1.SayHello);
APointer^.Data:=Self;

FList.Add(APointer);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
APointer:PMethod;
begin
APointer:=FList[0];

TMyMethod(APointer^)('hahah');
end;

end.

--------------------------------------------------------------

不过,如果真的要保存多个类实现的相同方法,可以考虑使用接口。多个类实现相同的 IInterface。然后在保存的地方使用 TInterfaceList 来保存多个Interface 的实例。
系統時間:2024-04-26 21:57:35
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!