delphi的interface编程注意问题

1.不支持继承
2.不能从接口获得实现类,如:
ITest = interface
...
end;

TTest = class(TObject, ITest)
...
end;

...
var
  tmpITest: ITest;
  tmpTTest: TTest;
  tmpTTest2: TTest;
...
  tmpITest := tmpTTest;//正确
...
  TTest(tmpITest).xxx();//不正确,运行期非法地址访问错误。
  tmpTTest2 := tmpITest;
   tmpTTest2.xxx();不正确,运行期非法地址访问错误。



3.接口设置为nil的情况
tmpI: ITest;
...
tmpI := nil;
//这个时候,delphi会调用function _IntfClear(var Dest: IInterface): Pointer;
//该函数内部调用了_Release
//所以delphi编程的com对象释放就是设置为nil就好(directX,com,com+等)
如果不想delphi默认调用函数_IntfClear可以怎么做
Pointer(tmpI) := nil;
强制转化为指针操作



4.对于类引用了接口的情况,delphi是先释放自己,在释放引用的接口的实现对象.
ITest = interface
...
end;

TTest = class(TObject, ITest)
...
  second: ITest;
  procedure SetSecondITest(aITest: ITest);
end;

procedure TTest.SetSecondITest(aITest: ITest);
begin
  second := aITest;
end;

procedure Test();
var
t1, t2: TTest;
i1, i1: ITest;
begin
t1 := TTest.Create();
i1 := t1;
t2 := TTest.Create();
i2 := t2;
t1.SetSecondITest(i2);
t2.SetSecondITest(i1);
end;
结果是delphi异常错误
t1释放的时候,先自己释放后,接着把i2的对象t2释放掉了,所以t2的释放就不对了。
注释掉"t1.SetSecondITest(i2);"会发现t2先释放,然后t1释放
注释掉"t2.SetSecondITest(ii);"会发现t1先释放,然后t2释放
(可以通过在destructor函数打印消息获得谁在释放)


5.
  结合3和4会发现,如果做一个接口的实现类的接口列表会有隐藏问题
  操作列表的时候,如果释放了列表保存的指针(:=nil)/释放列表的时候会释放对应的对象
  这个是不允许的!!!释放列表的时候最好做Pointer(tmpI) := nil;这样的操作
  才不容易引起一些莫名其妙的异常错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值