Getting object as a result from func/proc in Delphi - delphi

What is the best practice for returning simple objects from functions / procedures in delphi?
eg. 2 kinds of code:
pass created object as reference, populate object in Proc, destroy it afterwards
procedure Proc(var Obj: TMyObject);
begin
// populate Obj
end;
O := TMyObject.Create;
try
Proc(O);
// manipulate populated object
finally
O.Free;
end;
or
get created object as result from function, destroy after manipulation
function Func: TMyObj;
begin
Result := TMyObj.Create;
end;
O := Func;
if O <> nil then
begin
try
// manipulate
finally
O.Free;
end;
end;

There is no best practice. The primary thing you should do, though, is to make sure it's always clear who is responsible for destroying the object at any given time, even when an exception occurs.
There's nothing wrong with a function creating a new instance and returning it. Such a function is a factory. You can treat it just like a class's constructor, so you should make sure that it behaves like a constructor: Either return a valid object or throw an exception. It never returns a null reference.
function Func: TMyObj;
begin
Result := TMyObj.Create;
try
Result.X := Y;
except
Result.Free;
raise;
end;
end;
That's an exception-handling pattern you don't see very often, but it's important for this style of function. Returning the object transfers ownership from the function to the caller, but only if it manages to execute completely. If it has to leave early because of an exception, it frees the object because the caller has no way to free it itself. (Functions that terminate due to an exception do not have return values.) The caller will use it like this:
O := Func;
try
writeln(O.X);
finally
O.Free;
end;
If there's an exception in Func then O never gets assigned, so there's nothing available for the caller to free.
When the caller creates the object and you pass it to another function to initialize it, do not make the parameter a "var" parameter. That places certain restrictions on the caller, who must use a variable of exactly the type requested by the function, even if some descendant type was created instead.
Such a function should not free the object. The caller doesn't grant ownership responsibility to the functions it calls, especially when it plans on using the object after the function returns.

It depends on the lifetime of the object and on who is responsible for it.
Most of the time objects should be created and destroyed by the same entity.
Let's say your method fills a TStringList with results from parsing a file.
Should you let that function create the TStringList, or should you create it and pass as a reference?
I find it more readable to create it, pass it as reference, and later destroy, all in consecutive lines of code.
Now let's consider that you have a function that returns a TCustomer, for each customer added. In that case I would use a function, because I suppose that my entity would have a list, or something, of customers responsible for destroying them when not needed.

It is a common Delphi idiom to let the caller create the object and pass it as a parameter. Note that you don't have to declare it var in almost all cases.
procedure Proc (Obj : TMyObject)
begin
Obj.SomeProperty := 'SomeValue';
...
end;
Calling Code:
Obj := TMyObject.Create;
try
Proc (Obj);
finally
FreeAndNil (Obj);
end;
This avoids confusion about who has to free the object. Note that if you have a chain of method calls it can quicky become very complicated to keep track of objects that need to be freed somewhere along the line.
One more drawback: having creation and destruction scattered in the code makes it impossible to use try...finally blocks, which is just another helpful idiom to avoid resource leaks.
If you want your method to create the object, I would make it explicit in the function name, something like CreateAndInitializeList sounds right to me.

My rule is to have ownership and creation altogether. I always have the creator be the owner and thus have the responsability of destroying the object. The creation of the object is explicit in the invocation code, it is never a side effect of the invocation.
So the usual signatures of my functions are
function Func(o:tMyO): TMyO;
begin
// ....
Result := o;
end;
this way I may do either
o := func(TMyO.create);
or
o := TMyO.create;
// ...
func(o);

As mentioned, in general the same entity that created the object should free it and that means that the caller should create the object reference rather than having it done inside the function.
However, this is only possible if the caller knows the exact type of the item to be returned rather than a supertype. For instance:
var E: TEmployee;
E := CreateEmployee(EmployeeID); // Could return TEmployee or subclasses TManager or TRetiredEmployee
try
E.SendEmail(MessageText);
if (E is TRetiredEmployee) then
E.PrintLetter;
finally
E.Free;
end;
In cases like this, I find it's helpful to include the word "Create", or other indicator, in the name of the factory function I'm calling.

I often use the construct
FUNCTION SomeFunction(SL : TStrings = NIL) : TStrings;
BEGIN
IF Assigned(SL) THEN Result:=SL ELSE Result:=TStringList.Create;
// Use Result for the remainder of the function
END;
That way, I can use it both as a PROCEDURE with a passed-in reference, and as a FUNCTION which creates the instance itself.

Related

Delphi function return class object

In addition to this question I have made some tests and researches on the docwiki. My conclusion is that this kind of code should work without memory leaks:
function testResultObject: TClassA;
begin
Result := TClassA.Create;
Result.DoSomething;
end;
And then somewhere I can call the above code in this manner:
var k: TClassA;
begin
k := testResultObject;
try
//code code code
finally
k.Free;
end;
end;
As Remy suggested in the answer it's better to avoid this way of doing things and instead use something like testResultObject(x: TClassA): boolean. In this case the return true/false can tell me if everything went fine and I am passing an object already created.
Look at this code:
function testResultObject: TClassA;
begin
Result := TClassA.Create;
try
Result.DoSomething;
except
Result.Free;
end;
end;
The problem with the first version above of the function is that DoSomething could raise an exception and if so I'll leak memory. Can the second implementation with try-except be a solution? For sure later I'll have to check if the result is assigned or nil.
I agree that (as already said above) the testResultObject(x: TClassA): boolean would be better. I was just wondering if the return-a-class function way could be fixed as I've written.
Your code has serious problems. In case of an error, it swallows the exception, and returns an invalid object reference.
This is easy to fix. The canonical way is as follows:
function testResultObject: TClassA;
begin
Result := TClassA.Create;
try
Result.DoSomething;
except
Result.Free;
raise;
end;
end;
Either the function succeeds and returns a new object. Or it fails, cleans up after itself, and raises an exception.
In other words, this function looks and behaves just like a constructor. You consume it in the same way:
obj := testResultObject;
try
// do things with obj
finally
obj.Free;
end;
Your second approach works, but has 2 serious problems.
By swallowing all exceptions, (as J pointed out) you'll hide the fact that something went wrong.
There's no indication to the caller that you've created an object that the caller is responsible for destroying. This makes using the function more error prone; and easier to cause memory leaks.
I would recommend the following improvement on your second approach:
{Name has a clue that caller should take ownership of a new object returned}
function CreateObjectA: TClassA;
begin
{Once object is successfully created, internal resource protection is required:
- if no error, it is callers responsibility to destroy the returned object
- if error, caller must assume creation *failed* so must destroy object here
Also, by assigning Result of successful Create before *try*:
The object (reference) is returned
**if-and-only-if**
This function returns 'normally' (i.e. no exception state)}
Result := TClassA.Create;
try
Result.DoSomething; {that could fail}
except
{Cleanup only if something goes wrong:
caller should not be responsible for errors *within* this method}
Result.Free;
{Re-raise the exception to notify caller:
exception state means caller does not "receive" Result...
code jumps to next finally or except block}
raise;
end;
end;
The most important benefit of the above create function is that: as far as any caller/client code is concerned, it behaves exactly like a normal TObject.Create.
And so the correct usage pattern is exactly the same.
Note that I'm not keen on J's FreeAndNil suggestion because if calling code doesn't check if the result was assigned: it is likely to AV. And code that does check the result correctly will be a little messy:
var k: TClassA;
begin
k := testResultObject; {assuming nil result on failed create, next/similar is *required*}
if Assigned(k) then {Note how this differs from normal try finally pattern}
try
//code using k
finally
k.Free;
end;
end;
NB: It's important to note that you cannot ever have your caller simply ignore memory management; which brings me to the next section.
All the above aside, there is much less chance of making careless mistakes if your testResultObject takes an input object that you require the caller to create and manage its lifetime as needed. I'm not sure why you're resisting that approach so much? You cannot get simpler than the following without resorting to a different memory model.
var k: TClassA;
begin
k := TClassA.Create;
try
testResultObject(k); {Where this is simply implemented as k.DoSomething;}
//more code using k
finally
k.Free;
end;
end;
The only problem with this :
function testResultObject: TClassA;
begin
Result := TClassA.Create;
try
Result.DoSomething;
except
Result.Free;
end;
end;
Is that you have no way of knowing whether the function was successful. Freeing an object does not alter the reference; the variable will still point to the (now) invalid memory location where the object used to exist. You must explicitly set the reference to nil if you want the consumer to be able to test if the reference is valid. If you want to use this pattern (having the consumer test for nil) then you would need to do :
try
Result.DoSomething;
except
FreeAndNil(Result);
end;
This way the caller can test the result for nil (using Assigned or otherwise) as you intended. This still isn't a very clean approach, however, since you're still swallowing exceptions. Another solution might be to simply introduce a new constructor or alter the existing one. For example
TFoo = class
public
constructor Create(ADoSomething : boolean = false);
procedure DoSomething;
end;
constructor TClassA.Create(ADoSomething: Boolean = False);
begin
inherited Create;
if ADoSomething then DoSomething;
end;
procedure TClassA.DoSomething;
begin
//
end;
This way you can get rid of all of the exception handling and just call this as :
function testResultObject: TClassA;
begin
Result := TClassA.Create(true);
end;
Since you've now pushed the DoSomething execution into the constructor any exceptions will naturally automatically call the destructor and your memory management problems go away. The other answers also have good solutions.

Delphi - Down casting object does not call base method

I have a base object type : TBServiceBookings and then I've derived another object type from that : TBServiceQuotes
So when my form is created I decide which object to use. In this instance I've created the derived object.
if fScreenType = ST_NewAppointment then
fBookingObject := TBServiceBookings.CreateServiceBookings(nil,botSingle)
else
fBookingObject := TBServiceQuotes.CreateServiceQuotes(nil,botSingle);
At some stage I want to call a method of the base class only. So I cast the derived object to the base type and call it's method, but it keeps on going to the derived method - which I don't want.
I've tried:
1) fBookingObject := TBServiceBookings(fBookingObject);
fBookingObject.SetupNewAppointmentScreen;
2)
TBServiceBookings(fBookingObject).SetupNewAppointmentScreen;
3)
(fBookingObject as TBServiceBookings).SetupNewAppointmentScreen;
What am I missing? Why does the derived method get called each time even though I've downcasted specifically to call the base method?
The only option I have left is to create a new variable of the base type and then carry on with that. But I already have a form variable which is my object, I just want to call a specific base class method.
Any help appreciated please!
Besides the question that lies behind your question "where do you need this unusual and somewhat suspicious construct for?", there are some possibilities to access an ancestor virtual method.
Really ugly: change the type of your component:
var
SaveType: TClass;
begin
SaveType := Self.ClassType;
PClass(Self)^ := TAncestor;
try
Self.AncestorMethod;
finally
PClass(Self)^ := SaveType
end;
end;
Cast the method instead of the class:
type
TInstanceMethod = procedure(Instance: TObject);
begin
TInstanceMethod(#TAncestor.AncestorMethod)(Self);
end;
Employ a class helper:
type
TAncestorHelper = class helper for TAncestor
procedure AncestorMethodViaHelper;
end;
procedure TAncestorHelper.AncestorMethodViaHelper;
begin
inherited AncestorMethod;
end;
begin
Self.AncestorMethodViaHelper;
end;
When in need, I myself always use the second solution. But that is only when dealing with ancestors I cannot change, e.g. the VCL. Within your own framework, you would never need these hacks because you can just redesign.
Well if the class is yours, you have full control, so just don't override the base method you want to call. Like :
fBaseObject.ThisMethodBase; { calls the original }
fDerivedObject.ThisMethod; { calls the new one }
Seems like the simplest way to do it. Also remember you can simply call the Inherited method from your overriden method. So if you want to get creative you can pass a boolean that indicates if you want the base functionality. Like :
type
TX1=class
function ThisMethod(whatever:Integer;callOldOne:Boolean=false):integer;virtual;
end;
TX2=class(TX1)
function ThisMethod(whatever:Integer;callOldOne:Boolean=false):integer;override;
end;
function TX1.ThisMethod(whatever:Integer;callOldOne:Boolean=false):integer;
begin
result:=1;
end;
function TX2.ThisMethod(whatever:Integer;callOldOne:Boolean=false):integer;
begin
if callOldOne then result:=inherited ThisMethod(whatever) else Result:=2;
end;
Object oriented programming is fun.

How to set a record field as 'Procedure of object' before an object exists so that it can run

Very un-snappy title I know.
I have a series of text lines that I need to perform certain operations on in a certain order. I have come up with a means of doing this by defining the following record structure:
TProcessOrderRecord = record
RecordTypes: TByteSet;
InitialiseProcedure: TPreScanProc;
ProcessProcedure: TProcessRecord;
FinaliseProcedure: TEndScanProc;
end;
AProcessOrderArray = array of TProcessOrderRecord;
Initialise tends to call a constructor which will fill a field in the host object.
Process will be a procedure on the object which will be called for each text line that matches one of the record types in RecordTypes.
Finalise will tend to call the destructor and possibly do any checks when it knows that the full set of records has been processed.
The means of processing this array is quite straightforward:
procedure TImport.ScanTransferFile;
var
i: integer;
lArrayToProcess: AProcessOrderArray;
begin
lArrayToProcess := SetUpProcessingOrder(NLPGApp.ImportType);
for i := low(lArrayToProcess) to high(lArrayToProcess) do
begin
ProcessRecordType(lArrayToProcess[i].RecordTypes, lArrayToProcess[i].InitialiseProcedure, lArrayToProcess[i].ProcessProcedure, lArrayToProcess[i].FinaliseProcedure);
end;
end;
procedure TImport.ProcessRecordType(const RecordTypesToFind: TByteSet; PreScanProcedure: TPreScanProc; OnFindRecord: TProcessRecord; OnCompleteScan: TEndScanProc);
var
lLineOfText: string;
lIntegerRecordID: byte;
begin
if Assigned(PreScanProcedure) then PreScanProcedure;
try
if assigned(OnFindRecord) then
begin
Reader.GoToStartOfFile;
while not Reader.EndOfFile do
begin
lLineOfText := Reader.ReadLine;
lIntegerRecordID := StrToIntDef(GetRecordID(lLineOfText), 0);
if lIntegerRecordID in RecordTypesToFind then
begin
try
OnFindRecord(lLineOfText);
except
on E: MyAppException do
begin
// either raise to exit or log and carry on
end;
end;
end;
end;
end;
finally
// OnCompleteScan usually contains calls to destructors, so ensure it's called
if Assigned(OnCompleteScan) then OnCompleteScan;
end;
end;
My problem is that I want to define a record as such:
RecordTypes = [10]
InitialiseProcedure = ProcToCreateFMyObj
ProcessProcedure = FMyObj.do
FinaliseProcedure = ProcToFreeFMyObj
This compiles fine, however when ProcessProcedure is called, as FMyObj was nil when the ProcessProcedure is set, the instance of TMyObj is nil even though FMyObj is now set. Is there any clean way to get the record to point to the instance of FMyObj at the time of calling rather than at the time of first assignment?
At present I have resorted to having 'caller' methods on the host object which can then call the FMyObj instance when needed, but this is creating quite a bloated object with lots of single-line methods.
Edit to clarify/complicate the problem
Sometimes one instance of FObj can handle more than one types of record (usually if they have a master-detail relationship). In this case, InitialiseProcedure of the first record type will create FObj, FinaliseProcedure of the second record will free FObj and each record's ProcessProcedure can reference different procedures of FObj (do1 and do2).
At present I have resorted to having 'caller' methods on the host object which can then call the FMyObj instance when needed, but this is creating quite a bloated object with lots of single-line methods.
That is the right solution. Since the instance is not available at the point of initialisation you have no alternative.
When you use of object you are defining something called a method pointer. When you assign to a variable of method pointer type, the instance is captured at the point of assignment. There is no mechanism for the instance associated with a method pointer to be dynamically resolved. The only way to achieve that is to use runtime delegation, which is what you are currently doing. As is so often the case, another layer of indirection is used to solve a problem!
Your record that contains a number of methods looks awfully like an interface. I suspect that the most elegant solution will involve an interface. Perhaps at the point of calling you can call a function that returns an interface. And that function will using the value of FMyObj at the time of calling to locate the appropriate interface.
Yes it is possible to make additional runtime initialization of your record:
var
A: TProcessOrderRecord;
begin
..
TMethod(A.ProcessProcedure).Data:= FMyObj;
..
end;
though I would prefer a different solution, like the one you already use.

How can I check whether an object reference is still valid?

I have an issues where I am trying to determine if a reference to an object is valid. But it seems to be returning strange results.
procedure TForm1.Button1Click(Sender: TObject);
var form1 : TForm;
ref2 : TControl;
begin
form1 := TForm.Create(nil);
form1.Name := 'CustomForm';
form1.Parent := self; //Main Form
form1.Show;
ref2 := form1;
showmessage(ref2.ClassName+' - '+ref2.Name+' - '+BoolToStr(ref2.visible,true));
freeandnil(form1);
showmessage(ref2.ClassName+' - '+ref2.Name+' - '+BoolToStr(ref2.visible,true));
end;
The first showmessage returns - "TForm - CustomForm - True" (Just like I would expect it to).
The second showmessage return - "TForm - - False". I was actually hoping for some kind of access violation that I could then trap and know that the reference isn't valid.
In my application I need to compile a list of random TForm descendants as they are created and then check later if they have gone away (or are not visible). Unfortunately it is a plugin based system so I can go change all of these Forms to post a "I'm done Message."
Would code like this be safe to use (assuming I actually am checking for access violations)? Does anybody have any ideas what is happening.
Thanks
The problem is that with a certain likelyhood the memory accessed is still reserved by the Delphi memory manager. In that case Windows does not generate any kind of access violation, because that memory belongs to you!
One possibility is to switch to a different Delphi memory manager which can detect the use of freed objects. FastMM4, for example, has several "memory hygiene" checks, which are very useful for debugging, but even then you won't catch all of these errors immediately.
You can download FastMM4 from SourceForge.
Any TComponent (e.g. a TForm descendant) can register for notifications when other components are destroyed.
In your form, call FreeNotification(form) for each form that you wish to be notified of the destruction of. Then on the same form override the Notification() method. When any form (or other component) for which you have called FreeNotification() is destroyed, your Notification() method will be called with a Component parameter referencing the form and an Operation of opRemove.
If I've understood what it is you are trying to achieve, I think this should be enough information to devise an approach to do what you need.
After
freeandnil(form1);
the Delphi memory manager just marks the memory allocated by form1 as free, but all form1 data is still there, and can be accessed via ref2 until the memory manager reuse the freed memory for some other object(s).
You can't check that way if ref2 references a valid object or not. Code like this can't be safe, it is actually a bug.
If you want to obtain a 100% access violation modify the code as follows (here ref2^ = nil if form1 is freed):
procedure TForm1.Button1Click(Sender: TObject);
var form1 : TForm;
ref2 : ^TControl;
begin
form1 := TForm.Create(nil);
form1.Name := 'CustomForm';
form1.Parent := self; //Main Form
form1.Show;
ref2 := #form1;
showmessage(ref2^.ClassName+' - '+ref2^.Name+' - '+BoolToStr(ref2^.visible,true));
freeandnil(form1);
showmessage(ref2^.ClassName+' - '+ref2^.Name+' - '+BoolToStr(ref2^.visible,true));
end;
There is no reliable way to do what you are trying to do using the technique you're attempting. Forms that have "gone away" may have their memory reused, possibly even for a new form.
At best, you could work some mechanism whereby you cache the results of iterating Screen.Forms, but you can still fall foul of accidental duplicates, where a form gets destroyed and another gets reallocated and gets the same object address. That scenario is less likely than the memory being reused for some other object, however.
In a similar case I am using a singleton object that keeps a list of all the created forms.
Each form has a field with a reference to this Object.
TMyForm = class(TForm)
private
//*** This is the reference to the singleton...
FFormHandler: TFormHandler;
public
...
//*** you might want to publish it as a property:
property FormHandler: TFormHandler read FFormHandler write FFormHandler;
end;
You can set this reference e.g. when calling the constructor:
TMyForm.Create(aFormHandler: TFormHandler; aOwner: TComponent)
begin
FFormHandler := aFormHandler;
inherited Create(aOwner);
end;
(Or you could set the field from outside directly after creating the form if you don't want to change the parameters of the constructor).
When the form ist destroyed it notifies the handler and tells him to remove the form from the list - something like that:
TMyForm.Destroy(Sender: TObject);
begin
FFormHandler.RemoveFromFormList(Self);
inherited;
end;
(The details of the track-keeping are not included in the expample - e.g. a method "AddToFomList" or something alike would be needed)
There is one very interesting memory manager. It is called SafeMM: http://blogs.embarcadero.com/medington/2009/10/16/24839 But still it is for debugging only.
Given that you cannot modify the code that is out there in the plugins, all the good solutions about how to write safer code are not applicable to your case.
You have 1 way of doing it by
checking if an Object reference is
still what it's supposed to be by
looking up the VMT. This idea was
first published by Ray Lischner (who advocated for FreeAndNil for that very reason) and
later by Hallvard Vassbotn: see
this SO answer.
Another, better but introducing major slowdown, is to use FastMM4 in FullDebugmode to have it to replace all the freed objects by a TFreeObject instance instead of simply releasing the memory to the available pool.
Note that both methods do not prevent a false positive if another instance of the same class happens to be created at the same memory address. You get a valid object of the right type, just not the original one. (Unlikely in your case, but possible)
it is as simple as comparing against NIL:
// object declaration
Type object;
object = new Type();
...
// here you want to be sure of the existance of the object:
if (object <> nil )
object.free;
If you cannot test in another manner, you can use this as a last resort±
function IsValidClass( Cls: TClass ): Boolean;
var
i: Integer;
begin
for i := 0 to 99 do begin
Result := ( Cls = TObject ); // note that other modules may have a different root TObject!
if Result then Exit;
if IsBadReadPtr( Cls, sizeof( Pointer ) ) then Break;
if IsBadReadPtr( Pointer( Integer( Cls ) + vmtParent ), sizeof( Pointer ) ) then Break;
Cls := Cls.ClassParent;
end;
Result := False;
end;
function IsValidObject( Obj: TObject ): Boolean;
begin
Result := not IsBadReadPtr( Obj, sizeof( Pointer ) ) and IsValidClass( Obj.ClassType ) and not IsBadReadPtr( Obj, Obj.InstanceSize );
end;
IsBadReadPtr comes from Windows.

Somehow COM object instance gets lost

I have a main app and a type library contains 2 COM objects, one is IFile, one is IFiles. IFiles creates IFile, and stores them in a TLIST, and has standard methods like Add, Remove etc. Both IFile and IFiles are TAutoObject.
"Add" method in IFiles is working fine, it simply creates IFile object [Code 1], and adds it to TList. Problem is IFile object instance gets lost in a very strange way. see [Code 2]
[Code 1]
function IFiles.Add(AFilename: String): IFile;
begin
Result := CoIFile.Create;
Result.Filename := AFilename;
// ShowMessage(IntToStr(Result._AddRef));
fFiles.Add(#Result);
end;
In the main app I have test code like this.
[Code 2]
var
i: Integer;
f: IFile;
Files: IFiles;
begin
Files := CoTIFile.Create;
for i:= 1 to 4 do
begin
// Create a dummy file object
f := Files.Add('Filename ' + IntToStr(i));
f._AddRef; // Not sure if AddRef works like this
// Prints out the last file
Memo1.Lines.Add(Files.Files[i-1].Filename);
end;
for i:= 0 to Files.Count-1 do
begin
f := Files.Files[i];
// F is nil at all time.
if (f<>nil) then Memo1.Lines.Add(f.Filename); // ! No print out.
end;
end;
From the 2nd loop, even though fFiles.Count = 4, but all contents have lost. Do I need some extra treatment in IFile to handle AddRef and Release? or the way IFiles.Add method I wrote is wrong?
Try using TInterfaceList rather than TList to store the instances of IFile. This may solve your problem.
The problem in your original code was that you were adding an IFile pointer to the list, but when you read a value out of the list later, you assigned the pointer directly to another IFile variable. So you had was was essentially a PIFile value stored in an IFile variable. Delphi generally allows you to assign the untyped Pointer type to any pointer-like type, including interfaces.
To fix your original code, you would need to write the second look something like this:
var
p: Pointer;
for i := 0 to Pred(Files.Count) do begin
p := Files.Files[i];
if not Assigned(p) then
continue;
f := IFile(p^);
if not Assigned(f) then
continue;
Memo1.Lines.Add(f.Filename);
end;
You were right to call f._AddRef in your first loop. When IFiles.Add returns, the reference count on the result is 1 because the value stored in the loop is a pointer, not the actual reference. You need to increment the reference count because f is going to be re-used for other values. Since the reference you're manually counting is stored in the FFiles list, it would be better to call _AddRef inside IFiles.Add instead of waiting until it returns.
When you clear the list, or as you remove items from the list, you would need to call _Release on all the interface references.
But Toby's answer gives the better idea: Use TInterfaceList to store a list of interfaces. TList simply isn't suited to the task by itself.
A final piece of advice: The "I" prefix on names is used to denote interface types. Interfaces don't have method implementations of their own. You've shown the implementation of IFiles.Add, so IFiles clearly isn't an interface type. It should be named TFiles instead, or maybe TFileList.
The COM objects i automaticly released if there is no references to it.
In Code 1 the COM object gets released at the "end" statement.
I think you need to creat a wrapper object, and that wrapper object is what you add to files.
In sory i don't have the time to creat an example right now.

Resources