Var
A : Array [1..4] of Integer;
B : Array [1..4] of Integer;
Begin
A := B;
不会像 loren-pechtel 所说的那样工作,问题 是我的 A 和 B 在不同的单位。那么,有没有办法从另一个类中的现有类型定义类型定义?
Var
A : Array [1..4] of Integer;
B : Array [1..4] of Integer;
Begin
A := B;
不会像 loren-pechtel 所说的那样工作,问题 是我的 A 和 B 在不同的单位。那么,有没有办法从另一个类中的现有类型定义类型定义?
在某个单元的接口块中定义类型,然后将该单元通过uses
子句包含在您需要该类型的其他单元中。
unit A;
interface
type
TMyArray = array [1..4] of Integer;
...
当您需要TMyArray
在另一个单元中使用时:
unit B;
interface
uses A;
...
var x : TMyArray;
或者,在单元 C 的接口部分定义您的类型,并在 A 和 B 中使用该单元。
Delphi 中的数组类型有点奇怪。看起来A 和 B是完全相同的类型,但 Delphi 并不认为它们是相同的。“Array [1..4] of Integer”出现了两次,所以Delphi认为有两种不同的类型。这只是德尔福的一个奇怪之处。我认为大多数其他语言都不会在意。在实践中这不是问题;这有点奇怪。也许有一个很好的理由。谁知道。正如其他人所说,解决方案是定义自己的类型,您可以将其放入一个单元中,其他单元可以使用。我只是提到这个数组类型的问题,因为它可能会让你感到困惑。
另一种方法,有点老派但仍然有效,是使用 ABSOLUTE 关键字来强制一个内存覆盖另一个,并使另一个类型兼容。例如,在单元 a 中,假设您有以下内容:
TYPE
TArrayA = Array[1..4] of integer;
然后在单元 b 中,您有以下内容:
TYPE
TArrayB = Array[1..4] of integer;
为了兼容性,您可以执行以下操作:
VAR
InstanceA : TArrayA;
InstanceB : TArrayB;
InstanceBasA : TArrayA ABSOLUTE InstanceB;
这样做是创建一个 ArrayA 类型的变量“InstanceBasA”,它覆盖与变量“InstanceB”相同的内存空间。这允许您执行以下命令:
InstanceA := InstanceBasA;
将数据从变量 a 移动到变量 b 的另一种方法是使用 MOVE 命令。例如,要从 ArrayA 移动到 ArrayB,您可以执行以下操作:
var
ArrayA : array[1..4] of Integer;
ArrayB : Array[1..4] of Integer;
begin
FillChar(ArrayB[1],SizeOf(ArrayB),#0);
ArrayA[1] := 1234;
ArrayA[2] := 3456;
ArrayA[3] := 7890;
ArrayA[4] := 9876;
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
Assert( ArrayA[4] = ArrayB[4], 'ArrayA[4] <> ArrayB[4]');
end;
这是因为数组以线性方式布局,因此您复制从第一个数组位置开始的字节,以获得数组的长度。
您可以强制编译器通过对它们进行类型转换来假设它们属于同一类型:
type
TIntArray = array[1..4] of integer;
begin
Assert(SizeOf(ArrayA) = SizeOf(TIntArray));
Assert(SizeOf(ArrayB) = SizeOf(TIntArray));
TIntArray(ArrayA) := TIntArray(ArrayB);
但是您应该确保两者实际上都是 array[1..4] ,否则您将覆盖一些内存。这就是我添加两个断言的原因。
只需在接口之后和实现之前在UnitB中使用 UnitA ...!!!!
永远,永远,永远不要使用这样的代码:
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
缺陷在哪里?您正在使用 SOURCE 大小来获取要移动的字节数,而不是 DESTINATION 大小!!!如果 SizeOf(A) > SizeOf(B) 你有一个缓冲区溢出并且你正在覆盖内存。如果你很幸运,你会得到一个 AV,如果你不是,你就有一个可利用的漏洞。始终使用目标大小要好得多,尽管这样您最终可以读取如果 Size(B) > Size(A) 不应该读取的内存,可能会暴露不需要的数据。无论如何,在移动数据时始终检查结构边界——一些公司在他们的代码中禁止这样的操作(即 memcpy() )。