你能为Delphi记录重载赋值运算符吗?

Mar*_*mke 3 delphi operator-overloading

我有一个包含动态数组的记录.将一个数组变量分配给另一个数组变量是正常的,实际上只分配了指向该数组的指针.这意味着当您这样做时,两个变量都指向同一个数组,直到您更改其中一个变量的大小.因此,当我想为变量分配一个单独的数组副本时,我使用Copy()函数.

但是,在这种情况下,我的数组是记录的字段:

  TMyRec = record
    Value: integer;
    &Array: array of integer;
  end;
Run Code Online (Sandbox Code Playgroud)

当我声明TMyRec类型的两个变量然后将它们分配给另一个时,两个记录中的"Array"字段将指向内存中的相同地址.

为了解决这类问题,我决定重载assign运算符,如下所示:

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;
Run Code Online (Sandbox Code Playgroud)

如果这样可行,在将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;
Run Code Online (Sandbox Code Playgroud)

有没有办法让我的操作员超载工作,因为我想要它?问题是我正在尝试重载默认赋值运算符.那可能吗?

Bar*_*lly 7

您可以将数组放在实现接口的对象实例中,并在记录中存储对该接口的引用.这样,当您尝试通过接口(以及通过对象)分配给数组时,它可以检查其引用计数并帮助进行写时复制语义.

或者,您可以使用类型不安全技巧来查找数组的引用计数,如果存在多个引用,则可以在写入之前手动复制; 但是如果动态数组实现发生变化,那将不受支持并会中断.

写了如何实现记录中包含的写时复制数组结构.它是作为泛型类型实现的,但没有什么能阻止你使用具体的数组类型,它只是不会如此通用.