CSDN博客

img capboy

delphi的interface编程注意问题

发表于2004/10/28 15:01:00  1634人阅读

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

相关文章推荐

img
取 消
img