TInterfacedObject在Delphi中是否建议不要使用? (200分)

  • 主题发起人 主题发起人 DreamTiger
  • 开始时间 开始时间
D

DreamTiger

Unregistered / Unconfirmed
GUEST, unregistred user!
最近写一个程序,想尝试interface模式,但是被他的释放过程搞得头昏脑胀,不知道在delphi中是否建议不要使用TInterfacedObject?

unit Unit1


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls


type
TForm1 = class(TForm)
Memo1: TMemo

Button1: TButton

procedure Button1Click(Sender: TObject)

private
{ Private declarations }
public
{ Public declarations }
end


var
Form1: TForm1


implementation

{$R *.dfm}

type
IIntf = interface
['{714D88EA-4825-44B7-AD0B-027AA0B1D6B1}']
procedure Print

end


TIntf = class(TInterfacedObject, IIntf)
public
procedure Print

constructor Create

destructor Destroy;override

end



{ TIntf }

constructor TIntf.Create

begin
Form1.Memo1.Lines.Add('TIntf.Create')

end


destructor TIntf.Destroy

begin
Form1.Memo1.Lines.Add('TIntf.Destroy')

inherited

end


procedure TIntf.Print

begin
Form1.Memo1.Lines.Add('TIntf.Print')

end


procedure TForm1.Button1Click(Sender: TObject)

var
intf:IIntf

imp:TIntf

begin
imp := TIntf.Create

Form1.Memo1.Lines.Add('after imp := TIntf.Create, refcount := ' + IntToStr(imp.RefCount))

intf := imp as IIntf

Form1.Memo1.Lines.Add('after intf := imp as IIntf, imp refcount := ' + IntToStr(imp.RefCount))

intf.Print

intf := nil

Form1.Memo1.Lines.Add('after intf := nil, imp refcount := ' + IntToStr(imp.RefCount))

imp.Print

intf := imp as IIntf
//出错
end


end.

输出结果:
TIntf.Create
after imp := TIntf.Create, imp refcount = 0
after intf := imp as IIntf, imp refcount = 1
TIntf.Print
TIntf.Destroy
after intf := nil, imp refcount = 20
TIntf.Print

搞不懂:
1、intf := nil后,TIntf就被Destroy了;
2、refcount怎么就变成20了。
3、都调用过了TIntf.Destroy,还能调用TInf.Print,只能说是内存还没有被覆盖了。

晕阿。
 
哈哈,这么好玩啊,我也来试试
 
你的constructor TIntf.Create少了一行
inherited Create;
还有,因为intf := nil后引用计数为0,所以TIntf就释放了
最后面的TInt.Print是不能保证的,而那个=20的refcount也是不能保证的,这与不同系统的内存管理有关
 
建议你用这样
intf := TIntf.Create as IIntf;
不要使用TIntf变量了。使用接口,这是DELPHI推荐的方式。
 
1. intf := nil后,TIntf就被Destroy了;
Delphi 对 intf 进行生存期自管理,就是这样的。
2. refcount怎么就变成20了。
对象都被析构了,怎么能正确访问对象的字段。
3. 都调用过了TIntf.Destroy,还能调用TInf.Print,只能说是内存还没有被覆盖了。
你的 Print 过程没有涉及对象自身的变量,几乎相当于一个普通过程,所以还能调用。
 
我也来试试
 
自己不算计数,这是我觉得比较奇怪的一点,呵呵。
 
...............
 
...............
 
转个链接
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2433841
 
老兄,TInterfacedObject为你实现了IUnknown中的几个基本方法,包括引用计数的管理和接口查询,否则您需要自己实现这些方法,楼上的富翁指出了问题所在,通过接口的引用计数来管理实现接口对象的生命周期。看看李维新出的InsideVCL吧。
 
嗯,我不是不明白接口怎么管理的,主要是对对象的理解除了偏差,原以为imp := TIntf.Create时,也会加上一个计数,事实上,对于TInterfacedObject,创建的对象本身是没有计数的。我的理解,对象只是在创建的时候用到,而在后面,应该只用接口,而不能再使用对象了。
 
1. intf := nil后,TIntf就被Destroy了;
Delphi 对 intf 进行生存期自管理,就是这样的。
2. refcount怎么就变成20了。
对象都被析构了,怎么能正确访问对象的字段。
3. 都调用过了TIntf.Destroy,还能调用TInf.Print,只能说是内存还没有被覆盖了。
你的 Print 过程没有涉及对象自身的变量,几乎相当于一个普通过程,所以还能调用。
 

Similar threads

I
回复
0
查看
546
import
I
I
回复
0
查看
603
import
I
S
回复
0
查看
764
SUNSTONE的Delphi笔记
S
I
回复
0
查看
594
import
I
后退
顶部