delphi 接口 对象 交叉引用

在delphi编程中有时会遇到类A,类B相互引用或者一方引用另一方的问题。这种问题无外乎以下几种做法。

1.很多人可能都用过的,delphi下有两个地方可以uses其他单元,假如类A,类B在不同的单元UnitA, UnitB且互相引用。一般UnitA interface uses UnitB; UnitB implementation UnitA,这样就可以了,不能同时在interface或implementation中互相引用,否则编译不过。这样虽然达到了目的,代码的耦合度非常高。

2.在其中一个定义函数原型,然后公布出来,让另一个实现。比如类A包含了类B(可以自由使用类B得可见接口),而类B想使用类A得接口,而UnitB是没有引用UnitA的,那么UnitB根本不知道有类A,如果对类B是少量的调用,可以在UnitB定义一些函数原型,然后类A实现这种原型的函数并将地址赋值给类B,这样类B可以调用自己的函数指正,无须知道A的情况。但若类B需要用到类A较多的接口时,这样做相当麻烦。

3.使用delphi的接口。delphi的接口比较像c++的头文件。他定义的只是一套规则,实现的类必须严格依照规则,把办法交给了实现者,而不是调用者。这里类A将那些需要提供给其他类使用的方法做成一个interface,加入在单元UnitIA,接口名为IA,类A实现IA。类B引用UnitIA单元并定义外部可见的IA类型成员变量。类A在生成类B时将接口赋予类B,类就可以正常的调用类A得方法。类B在释放自己时必须先释放自己的成员变量类A,但由于接口的引用计数问题,编译器发现类B得引用计数不为0,触发异常,不予释放。假如释放过程成功,在释放类B得变量时由于导致类A得计数为0,将导致类A的实例被自动释放,继续执行类A得析构函数必定异常。

IAIntf = interface
['{37BFA0BF-4952-47F8-AAB8-8FAAD36B0EE5}']
procedure test;
end;

// B通过接口引用A
TB = class
private
FIA: IAIntf; // A的接口
public

property IA: IAIntf read FIA write FIA;
end;

// B为A的成员变量, 此类给外部使用,
TA = class(TInterfacedObject, IAIntf)
private
FB: TB;
public
constructor Create;
destructor Destroy; override;

procedure test;
end;

 

//-----------------------------------------1----------------

var

  A: TA;

begin

   // 这样必定出错

  A := TA.Create;  // 此时A已被FB引用了一次

  //A.FB.IA := nil;  // 这样解除引用导致A被编译器释放(A.Destroy),下面的A.Free将触发异常

  A.Free;              // 由于BeforeDestruction判断RefCount<>0导致异常。

end;

 

//------------------------------------2-----------------------------

var

  A: TA;

  IA: AIntf;

begin

  // 这种是可行的,声明A是为了看引用计数,可以构造后自己赋值给IA

  A := TA.Create;  // 此时A已被FB引用了一次

  IA := A;        // A被引用二次

  A.FB.IA := nil;  // 将FB对A的引用解除,RefCount=1

  IA := nil;   // A的引用计数再次-1,编译器自动释放A

  // 到这里对象A已经被释放,不能再A.Free。或者上面的IA := nil不要也可以释放。

end;

原文链接: https://www.cnblogs.com/NewJourney/archive/2012/05/09/2491956.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    delphi 接口 对象 交叉引用

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/49872

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午1:29
下一篇 2023年2月9日 上午1:30

相关推荐