现在的位置: 首页 > 综合 > 正文

DELPHI中类之间的嵌套定义

2013年05月15日 ⁄ 综合 ⁄ 共 1820字 ⁄ 字号 评论关闭

由于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
.

抱歉!评论已关闭.