【问题标题】:Delphi reference counting for subclassesDelphi 子类的引用计数
【发布时间】:2018-01-15 21:18:42
【问题描述】:

说我有这样的情况:

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。上面的代码会不会泄露?

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

【问题讨论】:

  • 测试应该很容易,ReportMemoryLeaksOnShutdown 设置为 True 将在您的程序终止时启用简单报告。
  • @nil 在表单的 onCreate 中设置 ReportMemoryLeaksOnShutdown?
  • 我想设置的时候并不重要——至少在足够早的时候。我个人会将它设置在 dpr 文件中,因为我习惯于在那里查看。
  • 最后尝试什么?
  • @SertacAkyuz a := TImpl.Create;最终不受尝试的保护我的意思是

标签: delphi


【解决方案1】:

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

你可以使用,实际上你必须使用,接口引用来存储你的子类对象实例,你编码的方式。 (不使用接口引用来存储引用计数的对象实例会破坏引用计数机制)

以下代码不会泄漏,并且不需要 try...finally 块,因为销毁是自动的。

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

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

begin
  ReportMemoryLeaksOnShutdown := true;
  ...
end.

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

【讨论】:

  • 嘿 Dalija 我不能投票,但我得出了你的结论。谢谢!!
  • @Rosanna,现在你可以了 ;-)
  • 只是为了记录使用ReportMemoryLeaksOnShutdown:=DebugHook<>0;是更常见的使用ReportMemoryLeaksOnShutdown的方式我试图简化它:)
【解决方案2】:

感谢 cmets(@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。所以代码很好,不会泄露!

【讨论】:

    猜你喜欢
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 2011-08-01
    • 2015-09-24
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多