Posted on 2008-08-18 18:27
xyz 阅读(1473)
评论(0) 编辑 收藏 引用 所属分类:
Delphi
由于DELPHI不允许unit单元的循环引用,而类的成员在定义时,必须要用interface里的类型,因此要实现类成员的互相引用,必须用变通的方法.
unit1
interface
uses
,unit2,;
type
tA=class
private
bbb:tB;
end;
unit2
interface
uses
,unit1,;
type
tB=class
private
aaa:tA;
end;
上面的2个unit不能通过编译,因为循环引用了.如果不循环引用,又出现类型没定义。反正就是不能通过编译。
有人说尽量避免类的这种互相定义,实在要定义时就把这2个类放在一个unit中。但是这样并不符合我们的设想。
在什么情况下需要这种互相定义呢,我们假设一个老师只有1个学生,一个学生只有1个老师,那么一个学生,那他就有老师,因此他有一个成员变量,指向他的老师的。而这个老师也会有1个成员变量指向他的学生。这时就发生了嵌套定义。
由于unit不能循环引用的限制,实现这种嵌套好像只能放到一个unit中了,但是我们有不在一个unit的需要。那要如何实现呢。
我们知道在implementation中uses的unit不会发生循环引用,而类的实现部分(定义部分是在interface)恰好是在implementation,在implementation里uses的类型可以在implementation范围内引用。因此我们是可以在类方法的实现部分使用到另外一个类。但是在类的方法中定义的变量是局部的,一退出过程就消失了,不能随时引用。
我们知道对象实质是一个dword型的指针.只要我们传递另外一个类的指针保存起来,在要调用另外一个类的方法时再强制转换后使用。
具体测试在下面的2个unit中
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TA=class
private
{ Private declarations }
//tb:pinteger;
public
classB:pdword;
procedure setTB(p:pinteger);
procedure doTest;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
unit2;
{$R *.dfm}
var
aa:tA;
bb:tB;
procedure TForm1.Button1Click(Sender: TObject);
var
b:tB;
begin
aa:=tA.Create;
bb:=tb.Create;
aa.classB:=@bb;
bb.classA:=@aa;
b:=tB(aa.classB);
b.doTest;
end;
{ TA }
procedure TA.doTest;
begin
showmessage('AAA');
end;
end.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
tB=class
private
{ Private declarations }
//ta:pinteger;
public
classA:pdword;
procedure doTest;
end;
implementation
uses
unit1;
{ tB }
procedure tB.doTest;
begin
showmessage('BBB');
end;
end.