1

I am trying to create a class with a 2d array(arrscore) within the create method, I have done some research on this and this is as far as I have come.

constructor create(spriority, sSelOne, sSeltwo, sSelthree: string; arrcountry: array of string; arrscore: array of real);

Here is my declaration of my classes variables

type
  tMap = class
  private
    // variables
    priority, selone, seltwo, selthree: string;
    country: array of string;
    score: array of real;

This is my create code

 begin
  priority := spriority;
  selone := sSelOne;
  seltwo := sSeltwo;
  selthree := sSelthree;
  country := arrcountry;
  score := arrscore;
end;

This doesn't work as it is incompatible types of dynamic array and array of real. Thanks in advance.

Winter
  • 13
  • 3
  • 1
    I don't see any two-dimensional array. I see only two one-dimensional arrays. – Andreas Rejbrand Jun 29 '20 at 07:50
  • 1
    Don't pass open arrays by value. If you do then a copy is made and passed on the stack. This is inefficent and can lead to stack overflow. Use `const` parameters. What you then need to do is to replace the assignments to your dynamic arrays with code that allocates new arrays (use `SetLength`) and then to copy the values from the argument to your dynamic arrays in a loop. In modern Delphi you can use [`System.Generics.Collections.TArray.Copy`](http://docwiki.embarcadero.com/Libraries/Rio/en/System.Generics.Collections.TArray.Copy) instead of the loop – David Heffernan Jun 29 '20 at 07:58

1 Answers1

1

Yes, this is rather annoying.

If you use open array parameters, you traditionally have to copy the arrays the manual and tedious way:

var
  country: array of string; // dynamic array
  score: array of Real; // dynamic array

// open array parameters
constructor Create(...; const arrcountry: array of string; const arrscore: array of Real);
var
  i: Integer;
begin
  SetLength(country, Length(arrcountry));
  for i := 0 to High(arrcountry) do
    country[i] := arrcountry[i];
  // similarly for score/arrscore
end;

However, as David Heffernan points out, recent Delphi versions also provide the TArray.Copy<T> procedure:

SetLength(country, Length(arrcountry));
TArray.Copy<string>(arrcountry, country, Length(arrcountry));
SetLength(score, Length(arrscore));
TArray.Copy<Real>(arrscore, score, Length(arrscore));

But if you use dynamic array parameters instead, you can do

var
  country: TArray<string>; // dynamic array
  score: TArray<Real>; // dynamic array

// dynamic array parameters
constructor Create(...; arrcountry: TArray<string>; arrscore: TArray<Real>);
begin
  country := arrcountry;
  score := arrscore;
end;

Notice that the arrays will not be copied, so any change you make to country will affect the caller's array (because it is the same array).

If you want to copy, do

country := Copy(arrcountry);
score := Copy(arrscore);
Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384