本文介绍了"复制和QUOT;不创建动态数组的独立副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参考在的.

这是很清楚的写在做出动态数组的独立副本,使用Copy()函数。在这个环节发现的例子code也说明了副本之后,如果更改一个阵列,它不反映到另一个数组都是独立的副本。它不适合我,但是。副本以及之后,如果我改变一个阵列,其他阵列自动切换到接收因此暗示复制()只是做了X中相同的值:= Y会做。每文档中,X:= Y和X:=复制(Y)。是的的相同

It is quite clearly written that to make an independent copy of a dynamic array, use the Copy() function. Example code found at that link also illustrates that after the copy, if you change one array, it is not reflected into the other array as both are independent copies. It does not work for me, however. After the copy as well, if I change one array, the other array automatically changes to receive the same value thus implying that Copy() just did what X := Y would have done. Per documentation, "X := Y" and "X := Copy(Y)" are NOT same.

下面是我的code:

type
  TTestArray = array of TMyType; //Note: TMyType is a class and not a record.

var
  X, Y, Z: TTestArray;

begin
  SetLength(X, 1); //create first array
  X[0].testString := 'Test Y';
  Y := copy(X);
  X[0].testString := 'Test Z'; //re-assign another value
  Z := copy(X);
  X[0].testString := 'Test X';

此时的TestString字段应包含不同的文字。因此,

at this time, testString field should contain different text. So,

X[0].testString should be 'Test X'
Y[0].testString should be 'Test Y'
Z[0].testString should be 'Test Z'

然而,所有这三个只是测试X'在后的TestString因此暗示复制()没有创建阵列X.相反,所有三个数组都指向同一个内存位置的独立副本的价值。

However, all three just have 'Test X' as the value in testString thus implying that Copy() did not create independent copies of the array X. Rather, all three arrays are pointing to the same memory location.

任何方式可靠地创建(即做到什么,我想上面做)?

Any way to reliably create independent copies of dynamic arrays (i.e. accomplish what I am trying to do above)?

注意(后来添加): TMyType是一类,而不是一个纪录。所以,下面的每非常有益的意见,这是一类的情况下预期的行为。所以,我怎么会让在X到Y和Z的独立的副本在这种情况下?

NOTE (added later): TMyType is a class and not a record. So, per very helpful comments below, this is an expected behavior in case of a CLASS. So, how would I make independent copy of the X into Y and Z in this case?

注2:从主题行中删除错误。对不起,Embarcadero公司...

NOTE 2: Removed "Bug" from subject line. Sorry, Embarcadero...

注意3: TMyType必须是一个类。我有没有对其进行控制。它正在从一个打开仁科的一些功能的Web服务定义(WSDL)创建的。

Note 3: TMyType has to be a class. I have no control over it. It is being created from a web service definition (WSDL) which exposes some functionality of PeopleSoft.

推荐答案

的问题是,你已经定义 TMyType 为:

The problem is that you've defined TMyType as:

type
  TMyType = class(SomeObject)
  ....
  public
    testString: string;
  end;

在创建初始 TestArray ,它的获取充满对象本身,而只用指针这些对象。

When you create the initial TestArray, it does not get filled with the objects itself, but only with pointers to these objects.

这是怎么回事... 结果
因此,该阵列是这样的:

What's going on...
The array thus looks like this:

Array           contents of array     contents of the heap
-------------+----------------------+-----------------------
X[0]         |-> pointer_to_MyType1 |-> MyType1
X[1]         |-> pointer_to_MyType2 |-> MyType2

在副本的阵列,这是发生了什么:

When you copy the array this is what happens:

Array           contents of array            contents of the heap
-------------+------------------------------+-----------------------
Y[0]         |-> copy_of_pointer_to_MyType1 |-> MyType1
Y[1]         |-> copy_of_pointer_to_MyType2 |-> MyType2

你想看到什么... 结果
这是你希望发生什么:

What you would like to see...
This is what you expected to happen:

Array           contents of array
-------------+-------------------
X[0] or Y[0] |-> (copy of)MyType1
X[0] or Y[0] |-> (copy of)MyType2

如何做到这一点结果
但是为了要做到这有可能,你必须定义 TMyType 为:

type
  TMyType = record
  public
    TestString: string;
  end;

现在该记录本身将被存储在数组中,而不是一个指向别处存储的数据。

Now the record itself will be stored in the array and not a pointer to data stored elsewhere.

我会怎么做在X到Y和Z的独立的副本在这种情况下?

如果您想保留使用类,那么你就得写你自己的复制的版本;是这样的:

If you want to retain the use of classes then you'd have to write your own version of Copy; something like:

uses
  System.SysUtils, system.classes, Generics.Collections;

type
  TMyList<T: TPersistent, constructor > = class(TList<T>)
  public
    function CloneArray: TMyList<T>;
  end;

implementation

function TMyList<T>.CloneArray: TMyList<T>;
var
  i: integer;
  temp: T;
begin
  Result:= TMyList<T>.Create;
  for i:= 0 to SizeOf(self) -1 do begin
    temp:= T.Create;
    temp.assign(self.items[i]);
    Result.Add(temp);
  end; {for i}
end;

显然,上述code假设您可以使用一个参数的构造函数脱身。

Obviously the above code assumes that you can get away with using a parameterless constructor.

另请参阅:

这篇关于&QUOT;复制和QUOT;不创建动态数组的独立副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 20:21