怎样理解 type TX = procedure of object;(120分)

  • 主题发起人 主题发起人 chy578
  • 开始时间 开始时间
C

chy578

Unregistered / Unconfirmed
GUEST, unregistred user!
  我在书上找不到,看帮助又不在明白。(本人看E文全用词霸点)
 
就是一种Type而已,不要想得太复杂。
 
我也不太明白
好像是定义一种类型为一过程,之后便可以声明变量为此种过程类型。只是提出一种标准
以便使用 如 TNotify事件过程,其它倒没什么
 
把过程声明为变量
 
一般用在事件处理和回调函数中
 
TX1= Procedure 等于是定义了直接指向Procedure的指针
TX2=Procedure of Object 是指向类(Class)的方法(Method)的指针
关键在于所有类(Class)的实例(Object)的方法(Method)共享同一个类(Class)方法(Method)地址。
所以 这两个指针指向的方法不同,编译器处理的时候就要区别开来。
 
我,, 还是不太懂。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=965399
看Delphi帮助 Keywords: method pointers
 
只是过程变量而已啦
 
type TX = procedure of object
type TY = procedure

这里TX就是一种对象方法的类型;TY则是一种普通的过程。两者的区别就在于TX类型的方法必须在一个对象里。
如下:

type
TMyClass = class
private
procedure doIt1
//方法
end;

procedure doIt2
//过程
function doIt3:integer
//函数
implementation

{ TMyClass }
procedure TMyClass.doIt1;
begin
//
end;

procedure doIt2
//过程
begin
//
end;

function doIt3:integer
//函数
begin
//
end;
 
指向类(Class)的方法(Method)的指针
 
Delphi中的procedure ... of object和ANSI C++中指向类成员函数的指针其实还是有不同的,
后者是指向类的函数的指针,实现上就是一个32bit指针或者一个vtbl的索引;
前者则是指向对象的方法的指针,实现上是一个对象指针加上一个方法指针组成的,
TMethod = record
Code, Data: Pointer;
end;
因此在标准ANSI C++中给类成员函数指针赋值必须以类为前缀,如TTest::Hello,
而在Delphi中给对象方法指针赋值必须加上对象实例,如TestObj.Hello才行

一种投机的方法是可以通过TMethod将对象方法指针重定向到一个全局函数,如

type
TFakeEvent = procedure (const strMsg: string) of object;
...
private
FTestEvent: TFakeEvent;
procedure Hello(const strMsg: string);
public
property TestEvent: TFakeEvent read FTestEvent;
end;
...
//FTestEvent := Self.Hello;
TMethod(FTestEvent).Code := @ExternalHello;


TMethod(FTestEvent).Data := nil;
...
procedure TForm1.Hello(const strMsg: string);
begin
ShowMessage('Hello '+strMsg);
end;
,,,
//注意这里传一个假参数const Null:Pointer用来这里Self指针的堆栈占用空间
procedure ExternalHello(const Null: Pointer
const strMsg: string);
begin
ShowMessage('ExternalHello '+strMsg);
end;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(TestEvent) then
TestEvent('World');
end;
值得一提的是BCB为了兼容Delphi增加了一个__closure关键字,和of object
效果相同,但与标准c++的不同,说明如下

发信人: flier (小海->找啊找工作 :)), 信区: Programming
标 题: Re: 成员函数指针的问题
发信站: BBS 水木清华站 (Wed Mar 6 17:43:40 2002)

bcb里面对成员函数指针的支持实际上是有两个层面的

对应于C++标准的类成员函数指针和对应于Delphi中对象指针
我们先看看一个例子
class TTest
{
public:
void Hello(void) { ShowMessage("Hello")
}
};
如果要使用C++标准的函数指针
typedef void (TTest::*THelloFunc1)(void);
{
...
TTest t;
THelloFunc1 func1 = TTest::Hello;

(t.*func1)();
...


}
这个指针实际上是一个函数指针或者一个索引
(索引用于在vtbl中定位)
而如果使用Delphi中的对象指针则是
{
...
TTest t;
typedef void (__closure *THelloFunc2)(void);
THelloFunc2 func2;
func2 = t.Hello
//注意是对象+方法
func2()
//直接调用,因为已经绑定了对象和方法
}
注意这里的__closure关键字定义了一个函数指针
并不指向某种特定类型的类,而只是定义参数、返回值等
实际上这种指针有两个字段,分别保存指针指向的对象和对象的方法
这是在Delphi中为处理event而加入的特性,是bcb为使用vcl的扩展
和普通的C++成员函数指针不同,因此在赋值时必须加上对象才行

 
多人接受答案了。
 

Similar threads

回复
0
查看
1K
不得闲
D
回复
0
查看
867
DelphiTeacher的专栏
D
D
回复
0
查看
836
DelphiTeacher的专栏
D
后退
顶部