Can you overload the assignment operator for Delphi records?

I have a record containing a dynamic array. This is normal when you assign one variable of an array to another, in fact only a pointer to this array is assigned. This means that when you do this, both variables point to the same array until you resize one of them. Therefore, when I want to assign a separate copy of an array to a variable, I use the Copy () function.

In this case, however, my array is a write field:

  TMyRec = record
    Value: integer;
    &Array: array of integer;
  end;

When I declare two variables of type TMyRec and then assign them to each other, the "Array" fields in both entries will point to the same address in memory.

To solve this problem, I decided to overload the assignment operator as follows:

TMyRec = record
  Value: integer;
  &Array: array of integer;
public
  class operator Implicit(Value: TMyRec): TMyRec;
end;

class operator TMyRec.Implicit(Value: TMyRec): TMyRec;
begin
  Result := Value;
  Result.&Array := Copy(Value.&Array);
end;

, TMyRecord .

:

var
  Rec1, Rec2: TMyRec;
begin
  Rec1.Value := 10;
  SetLength(Rec1.Array, 1);

  //I expected the "Implicit" method to be invoked here (but it is not...)
  Rec2 := Rec1;

  //if I do that, the Rec1.Array[0] will also be changed to 1 - I don't want that to happen
  Rec2.Array[0] := 1;
end;

, ? , . ?

+3
3

, , . , (, , ), .

, , ; , .

I , copy-on-write, . , , .

+7

TMyRec:

pMyRec = ^TMyRec;
TMyRec = record
  Value: integer;
  _Array: array of integer;
public
  class operator Implicit(Value: pMyRec): TMyRec;
end;

class operator TMyRec.Implicit(Value: pMyRec): TMyRec;
begin
  Result := Value^;
  Result._Array := Copy(Value^._Array);
end;

procedure TForm1.Button1Click(Sender: TObject);
var R1, R2 : TMyRec;
begin
  R1.Value := 1;
  SetLength( R1._Array, 2);
  R1._Array[0] := 1;
  R1._Array[1] := 2;

  R2 := @R1;
  R2._Array[0] := 3;
end;
+3

. . "RecCopy", :

procedure RecCopy( const AFrom, ATo : TMyRec );
var
  I : integer;
begin
  ATo.Value := AFrom.Value;
  SetLength( ATo.Array, Length( AFrom.Array );
  For I := 0 to Length( AFrom.Array )-1 do
    ATo.Array[I] := AFrom.Array[I];
end;

, :-) .

+1

Source: https://habr.com/ru/post/1709815/


All Articles