Delphi引用子类的计数

时间:2018-01-15 21:18:43

标签: delphi

说我有这样的情况:

ITest = interface
 procedure somethingHere();
end;

TImpl = class(TInterfacedObject, ITest)
 procedure somethingHere();
end;

TImplSub = class(TImpl)

end;

鉴于上面的代码,如果我不使用try-finally语句,我可以使用这种代码而不会有任何内存泄漏:

var a: ITest;
begin
 a := TImpl.Create;
end;

子类是否相同?

var a: ITest;
begin
 a := TImplSub.Create;
end;

我认为由于TImplSub是TImpl的子类,因此TImplSub继承了父亲的TInterfacedObject和ITest。以上代码是否泄漏?

这可能没有关系,但我如何检查上面的代码是否泄漏?

2 个答案:

答案 0 :(得分:13)

使用_AddRef_Release方法触发接口引用的引用计数,在这种情况下,TInterfacedObject实现了这些方法。您的子类继承了该引用计数行为。

您实际上必须使用接口引用来存储子类对象实例,以及编码它的方式。 (不使用接口引用来存储引用计数对象实例中断引用计数机制)

以下代码不会泄漏,并且不需要try...finally阻止,因为破坏是自动的。

var a: ITest;
begin
 a := TImplSub.Create;
end;

要检查Windows编译器下的内存泄漏,可以使用ReportMemoryLeaksOnShutdown

begin
  ReportMemoryLeaksOnShutdown := true;
  ...
end.

在调查特定行为时测试对象是否被销毁的另一种方法是覆盖析构函数并在那里设置断点。

答案 1 :(得分:5)

感谢评论(@nil用户),我设法做了这样的测试

type
 ITest = interface
   procedure test;
 end;

 TProva = class(TInterfacedObject, ITest)
   procedure test;
 end;

 TProvaSub = class(TProva)
   procedure testDue;
 end;

然后如果您尝试运行此代码(在使用F9的调试模式下):

procedure TForm1.Button1Click(Sender: TObject);
var a: ITest;
begin    
 a := TProvaSub.Create;
 a.test;    
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown:=DebugHook<>0;
end;

当我关闭表格时,我不会有泄漏报告。

我的结论:TProvaSub内部有一块TProva(因为它是一个子类),所以它继承了_AddRef和_Release。所以代码很好,不会泄漏!