Unused interface link not broken

I had another error in my application caused by careless use of Delphi interfaces. When I pass an interface to a procedure that ignores this argument, the instance is never freed. See the following simple example:

ITest = interface procedure Test; end; Tester = class(TInterfacedObject, ITest) public procedure Test; end; Base = class public procedure UseTestOrNot(test : ITest); virtual; abstract; end; A = class(Base) public procedure UseTestOrNot(test : ITest); override; end; B = class(Base) public procedure UseTestOrNot(test : ITest); override; end; { A } procedure A.UseTestOrNot(test: ITest); begin test.Test(); end; { B } procedure B.UseTestOrNot(test: ITest); begin WriteLn('No test here'); end; // -------- Test --------------------------------------- var list : TObjectList<Base>; x : Base; t : ITest; begin ReportMemoryLeaksOnShutdown := true; list := TObjectList<Base>.Create; list.Add(A.Create); list.Add(B.Create); // 1 x Tester leak for each B in list: for x in list do x.UseTestOrNot(Tester.Create); // this is ok for x in list do begin t := Tester.Create; x.UseTestOrNot(t); end; list.Free; end. 

Could you explain what went wrong with the watch counter? Can you give any recommendation / guide (for example, β€œNever create a conjugate instance inside a function call [unless you know what is going on inside”).

The best solution I can come up with for this example is to write a template method in the Base class that saves the passed test instance and calls the abstract DoUseTestOrNot method.

EDIT Delphi 2010

+7
interface delphi delphi-2010
source share
2 answers

This is another manifestation of errors here .
I will add this to the QC report. Strike>

This no longer plays in Delphi XE update 1.

- Jeroen

+8
source share

Add a guide for you ITest Announcement

 ITest = interface ['{DB6637F9-FAD3-4765-9EC1-0A374AAC7469}'] procedure Test; end; 

Change the loop to

 for x in list do x.UseTestOrNot(Tester.Create as ITest); 

You must specify a GUID in order to be able to use as

Test.Create as ITest forces the compiler to add a release where the created object goes out of scope.

+8
source share

All Articles