2
Var
     A : Array [1..4] of Integer;
     B : Array [1..4] of Integer;

Begin
    A := B;

ここでローレン・ペクテルが言ったように 、問題は私にとってAとBが異なるユニットにあるということです。では、別のクラスの既存のものから型定義を定義する方法はありますか?

4

8 に答える 8

13

usesあるユニットのインターフェイス ブロックで型を定義し、その型が必要な他のユニットに句を介してそのユニットを含めます。

unit A;
interface
type
  TMyArray = array [1..4] of Integer;

...

TMyArray別のユニットで使用する必要がある場合:

unit B;
interface
uses A;

...
var x : TMyArray;
于 2009-04-03T20:20:20.937 に答える
1

もう 1 つのアプローチは、少し古い方法ですが、まだ機能します。これは、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;

これが行うことは、変数「InstanceB」と同じメモリ空間をオーバーレイするタイプ ArrayA の変数「InstanceBasA」を作成することです。これにより、次のコマンドを実行できます。

InstanceA := InstanceBasA;
于 2009-04-13T23:51:30.027 に答える
1

Delphi の配列型は少し奇妙です。A と B はまったく同じ型のように見えますが、Delphi はそれらが同じであるとは見なしません。「Array [1..4] of Integer」が 2 回出てくるので、Delphi は 2 つの異なるタイプがあると考えます。それは Delphi の奇妙なところです。他のほとんどの言語は気にしないと思います。実際には問題ありません。少し奇妙です。多分それには正当な理由があります。知るか。他の人が言ったように、解決策は、他のユニットで使用できるユニットに入れることができる独自のタイプを定義することです。混乱を招く可能性があるため、配列型のこの問題について言及します。

于 2009-04-04T01:31:09.147 に答える
0

インターフェイスの後、実装の前にUnitBで UnitA を使用するだけです ...!!!!

于 2009-04-28T10:47:42.657 に答える
0

それらを型キャストすることにより、コンパイラーにそれらが同じ型であると想定させることができます。

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] であることを確認する必要があります。そうしないと、一部のメモリが上書きされます。そのため、2 つのアサーションを追加しました。

于 2009-04-14T07:56:50.640 に答える
0

variablea から variableb にデータを移動するもう 1 つの方法は、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;

これは、配列が線形に配置されているという事実によって機能するため、最初の配列位置から始まる配列の長さのバイトをコピーします。

于 2009-04-14T00:00:29.147 に答える
0

絶対に、絶対に、絶対に、次のようなコードを使用しないでください。

// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );

欠陥はどこにありますか?DESTINATION サイズではなく、移動するバイト数を取得するために SOURCE サイズを使用しています!!! SizeOf(A) > SizeOf(B) の場合、バッファ オーバーフローが発生し、メモリを上書きしています。運がよければ AV を取得できますが、そうでない場合は、悪用可能な脆弱性があります。常に目的のサイズを使用する方がはるかに優れていますが、この方法では、Size(B) > Size(A) の場合にすべきではないメモリを読み取ってしまう可能性があり、不要なデータが公開される可能性があります。とにかく、データを移動するときは常に構造の境界を確認してください - 一部の企業は、このような操作 (つまり memcpy() ) をコードから禁止しています。

于 2009-08-21T10:25:02.963 に答える