Recent

Author Topic: Is there a procedure to initialize a variable number of objects at runtime?  (Read 4906 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1165
    • HowTos Considered Harmful?
Is there a procedure to initialize a variable number of objects at runtime in a single procedure?

I usually have initialize some variables like the TStringList type at the start of procedures and free them afterwards.It feels awkward to initialize the separately, like

Code: [Select]
listOne := TStringList.Create;
listTwo := TStringList.Create;
listTree := TString.Create;
{ etc, etc}

I would prefer a procedure like, with another for Free ing them a the end:

Code: [Select]
CreateStrings(listOne, listTwo, listThree);
CreateStrings([listOne, listTwo, listTree]); //using an array
Is there a procedure that can do something like this for a variable number of objects?

If it can't be done for arbitrary object types, then at least  types with the same Create signature?
Lazarus 3.0/FPC 3.2.2

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
It's possible create such functions. But first thing you need to decide is if they are all exactly TStringList type, or all kinds of TStrings variants, because that would complicate it? For freeing i'm thinking you could return an array reference from the creating function, so you don't need to specify each object for freeing procedure.

I don't remember exactly now if var typed array parameter can be written into, propably not. You might have to give array of pointer to each object. Here is some untested code:
Code: [Select]
type
  TObjectArrayRef = array of TObject;
...
function CreateStringLists(var vars: array of TStringList): TObjectArrayRef;
var i: integer;
begin
  setlength(result, length(vars));
  for i:=low(oArray) to high(oArray) do begin
    vars[i]:=TStringList.Create;
    result[i]:=vars[i];
  end;
end;

function CreateObjects(var vars: array of TObject; vTypes: array of classType): TObjectArrayRef;
// Was it "classtype"? That answer can be found here on forums
var i: integer;
begin
  setlength(result, length(vars));
  for i:=low(oArray) to high(oArray) do begin
    vars[i]:=vTypes[i].Create;
    result[i]:=vars[i];
  end;
end;

procedure FreeObjects(oArray: TObjectArrayRef);
var i: integer;
begin
  for i:=low(oArray) to high(oArray) do
    oArray[i].Free;
end;

And of course doing procedures like this will slow down the program  :P  But if it's easier for the programmers eye then be my guest.
« Last Edit: December 23, 2013, 10:22:28 am by User137 »

vfclists

  • Hero Member
  • *****
  • Posts: 1165
    • HowTos Considered Harmful?
Can the admins move this topic to the General forum. I posted it this forum accidentally?
Lazarus 3.0/FPC 3.2.2

vfclists

  • Hero Member
  • *****
  • Posts: 1165
    • HowTos Considered Harmful?
Thanks for the examples. I will try them out.

In this case I prefer readability over speed.

It's possible create such functions. But first thing you need to decide is if they are all exactly TStringList type, or all kinds of TStrings variants, because that would complicate it? For freeing i'm thinking you could return an array reference from the creating function, so you don't need to specify each object for freeing procedure.

I don't remember exactly now if var typed array parameter can be written into, propably not. You might have to give array of pointer to each object. Here is some untested code:
Code: [Select]
type
  TObjectArrayRef = array of TObject;
...
function CreateStringLists(var vars: array of TStringList): TObjectArrayRef;
var i: integer;
begin
  setlength(result, length(vars));
  for i:=low(oArray) to high(oArray) do begin
    vars[i]:=TStringList.Create;
    result[i]:=vars[i];
  end;
end;

function CreateObjects(var vars: array of TObject; vTypes: array of classType): TObjectArrayRef;
// Was it "classtype"? That answer can be found here on forums
var i: integer;
begin
  setlength(result, length(vars));
  for i:=low(oArray) to high(oArray) do begin
    vars[i]:=vTypes[i].Create;
    result[i]:=vars[i];
  end;
end;

procedure FreeObjects(oArray: TObjectArrayRef);
var i: integer;
begin
  for i:=low(oArray) to high(oArray) do
    oArray[i].Free;
end;

And of course doing procedures like this will slow down the program  :P  But if it's easier for the programmers eye then be my guest.
Lazarus 3.0/FPC 3.2.2

 

TinyPortal © 2005-2018