2009-04-03 3 views
1
Var 
    A : Array [1..4] of Integer; 
    B : Array [1..4] of Integer; 

Begin 
    A := B; 

не будет работать, как Loren-pechtel сказал here проблема А и для меня в различных единицах измерения. Итак, есть ли способ определить определение типа из существующего в другом классе?Определение типов из других единиц в Delphi

ответ

11

Определите тип в интерфейсном блоке какого-либо устройства, а затем включите этот блок через пункт uses в другие блоки, где вам нужен этот тип.

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

... 

Когда вам нужно использовать TMyArray в другом блоке:

unit B; 
interface 
uses A; 

... 
var x : TMyArray; 
5

В качестве альтернативы, определить свой тип в интерфейсной части блока C и использовать данное устройство в А и В.

1

Типы массивов в Delphi немного странны. Это выглядит, как A и B, имеют одинаковый тип, но Delphi не считает, что они одинаковы. «Массив [1..4] Integer» появляется дважды, поэтому Delphi считает, что существует два разных типа. Это просто странность Delphi. Большинство других языков, мне кажется, все равно. На практике это не проблема; это немного странно. Возможно, для этого есть веская причина. Кто знает. Решение, как говорили другие, определяет ваш собственный тип, который вы можете поместить в единицу, которая может использоваться другими подразделениями. Я просто упоминаю этот вопрос о типах массивов, потому что это может вас смутить.

+0

Для этого есть веская причина - он позволяет вам делать типы отличными, даже если они технически одинаковы. Чем сильнее набирается текст, тем чаще компилятор ловит вашу ошибку, а не находит ее с помощью отладчика. –

+0

Не только типы массивов. ВСЕ структурированные типы. Вы можете определить две записи с одинаковой структурой, но они не одинаковые. Определите два класса с одинаковой структурой, и они не совпадают. –

1

Другой подход, немного старая школа, но по-прежнему работает, заключается в использовании ключевого слова ABSOLUTE, чтобы заставить память одного наложить другое, и сделать другой тип совместимым. Например, в блоке позволяет сказать, что у вас есть следующее:

TYPE 
    TArrayA = Array[1..4] of integer; 

затем в единицу б, у вас есть следующие:

TYPE 
    TArrayB = Array[1..4] of integer; 

Для совместимости, вы можете сделать следующее:

VAR 
    InstanceA : TArrayA; 
    InstanceB : TArrayB; 
    InstanceBasA : TArrayA ABSOLUTE InstanceB; 

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

InstanceA := InstanceBasA; 
0

Еще один способ перемещения данных из variablea в variableb должны использовать команду 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; 

Это работает тот факт, что массив запаздывающие в линейной форме, так что ваши копирования байт, начиная с первой позицией массива, для длины массива.

0

Вы можете заставить компилятор предположить, что они являются одной и той же типа, типажей их:

type 
    TIntArray = array[1..4] of integer; 

begin 
    Assert(SizeOf(ArrayA) = SizeOf(TIntArray)); 
    Assert(SizeOf(ArrayB) = SizeOf(TIntArray)); 
    TIntArray(ArrayA) := TIntArray(ArrayB); 

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

0

Просто используйте Unitá в UnitB после inteface и до реализации ... !!!!

0

Никогда, никогда, НИКОГДА не использовать такой код:

// 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)> Размер (A), возможно, отображал нежелательные данные. В любом случае, всегда проверяйте границы структуры при перемещении данных - некоторые компании запретили подобные операции (то есть memcpy()) из своего кода.

Смежные вопросы