Вопрос

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

Begin
    A := B;

Не будет работать, как сказал Лорен-Пехтель здесьПроблема в том, что 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 не считает, что они одинаковы. «Массив [1..4] целого числа» появляется дважды, поэтому Дельфи думает, что есть два разных типа. Это просто странность Дельфи. Я думаю, что большинство других языков будут все равно. Это не проблема на практике; Это просто странно. Может быть, есть веская причина. Кто знает. Решение, как говорили другие, определяет ваш собственный тип, который вы можете поместить в устройство, которое можно использовать другими подразделениями. Я просто упоминаю эту проблему типов массива, потому что это может сбить вас с толку.

Другой подход, немного старая школа, но все еще работает, - использовать абсолютное ключевое слово, чтобы заставить память одного для наложения другого и сделать другой тип совместимым. Например, в блоке 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;

Это создает переменную «ancessbasa» абортов типа, которая накладывает одно и то же пространство памяти, что и переменная «экземпляры». Это позволяет вам выполнить следующую команду:

InstanceA := InstanceBasA;

Еще один метод перемещения данных из variablea в variableb - это использование команды перемещения. Например, чтобы перейти из Арреи в 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);

Но вы должны убедиться, что оба на самом деле являются массивами [1..4] в противном случае, вы перезаписываете некоторую память. Вот почему я добавил два утверждения.

Просто используйте Unita в Unitb после Inteface и до реализация ...!!!!

Никогда, никогда, никогда не используйте код таким:

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

Где недостаток? Вы используете размер источника, чтобы получить количество байтов для перемещения, а не размер назначения !!! Если sizeof (a)> sizeof (b) у вас есть переполнение буфера, и вы перезаписываете память. Если вам повезет, вы получаете AV, если вы не имеете уязвимости. Гораздо лучше всегда использовать размер назначения, хотя таким образом вы можете в конечном итоге читать память, если не следует, если размер (b)> размер (а), возможно, разоблачение нежелательных данных. В любом случае, всегда проверяйте границы структуры при перемещении данных - некоторые компании запрещали такие операции, как это (т.е. memcpy ()) из их кода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top