首页 文章

Delphi引用子类的计数

提问于
浏览
10

说我有这样的情况:

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 回答

  • 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 (因为它泄漏了's a subclass) and so it inherits the _AddRef and _Release. So the code is good and doesn'!

  • 12

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

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

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

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

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

    begin
      ReportMemoryLeaksOnShutdown := true;
      ...
    end.
    

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

相关问题