Result := ITestFunc(OperationClass.Create).DoIt(Num1, Num2);
Nowhere is there a link to the accepted interface. The link is made when the interface is assigned to a variable or passed as a parameter by value. In fact, passing as a parameter by value, can be considered semantically equivalent to assigning a local variable in the call frame.
But nowhere in this code is a link used. So, since nothing refers to an interface, there is no mechanism for destroying it. Hence the leak.
var I: ITestFunc; begin I := ITestFunc(OperationClass.Create); Result := I.DoIt(Num1, Num2); end;
In this embodiment, reference is made upon appointment. When the local variable I leaves the scope, its reference count is reduced to zero and the implementation object is destroyed.
Please note that duty free reception is not needed here. The compiler knows very well that TTestFunc implements ITestFunc , and it is better to write your code like this:
var I: ITestFunc; begin I := OperationClass.Create; Result := I.DoIt(Num1, Num2); end;
As pointed out in the comments, you can remove the local variable and use the marked as cast:
Result := (OperationClass.Create as ITestFunc).DoIt(Num1, Num2);
A consequence of the implementation of the as cast is that an implicit local variable is declared to which the interface is assigned. This means that the reference count is incremented by one, and then reduced to zero when this implicit local area of โโthe sheet.
Finally, your TTestFunc class must have a virtual constructor, since you intend to create it using a metaclass.
David heffernan
source share