Having classes as return types for functions is a bad idea, because it can make things very complicated.
For example:
function foo: TSomeClass;
begin
Result := TSomeClass.Create;
Result.DoSomething;
end;
What happens if that DoSomething throws an exception? Well the instance reference is lost. So what you need to do is to always have a try-except block in such a function:
function foo: TSomeClass;
begin
Result := TSomeClass.Create;
try
Result.DoSomething;
except on e: Exception do
FreeAndNil(Result);
raise e;
end;
end;
If you simply pass that instance as a parameter:
procedure foo(inst: TSomeClass);
begin
inst.DoSomething;
end;
This is not required, as you typically have a try-finally block on the callsite anyway:
someInstance := TSomeClass.Create;
try
foo(someInstance);
...
finally
someInstance.Free;
end;
So giving the instance as parameter makes it much easier because you don't need a try-except block, which is required if the instance is created by the function, and more importantly, it is also cleaner because creation and destruction happens in the same block/function