- •Программная реализация формальных средств анализа и моделирования интегрированных систем ла
- •Примеры реализации пмо на Delphi
- •Реализация на основе записей (record)
- •Использование классов и объектных интерфейсов
- •Реализация с самостоятельным управлениям памятью
- •Реализация с использованием библиотеки шаблонов
- •Литература
Примеры реализации пмо на Delphi
Реализация модуля процедур векторной, матричной и кватернионной алгебры на Delphi может быть выполнена различными способами. Для непосредственного хранения данных (элементов векторов, матриц) удобно использовать динамические массивы, являющиеся частью языка и позволяющие не заботиться о механизмах выделения и удаления памяти. Объявление типов одномерного и двумерного динамических массивов действительных чисел с повышенной точностью (типа Extended) может иметь вид:
Type
T1DArray: array of Extended;
T2DArray: array of array of Extended;
Выделение
памяти для экземпляров таких типов
осуществляется вызовом системной
процедуры с переменным числом параметров
System.SetLength(arg,
,
,
…,
),
где arg – переменная типа
«динамический массив» размерности N,
а
– нужное количество элементов в каждом
измерении этого массива. Для освобождения
памяти достаточно выполнить присвоение
arg := nil
или явно указать нулевые размеры в
каждом измерении динамического массива:
System.SetLength(arg,
0, 0, …, 0). Для получения информации о
количестве элементов динамического
массива следует использовать функцию
System.Length(arg),
при этом допустимы обращения ко второму
и последующим измерениям массива:
System.Length(arg[
,
,
…,
]),
где
– номер интересующего элемента в первом
измерении,
– во втором и т.д. до измерения (N-1).
Динамический массив в Delphi – это ссылочный тип, т.е. при выполнении прямого присваивания в новую переменную будет скопировано не содержимое массива, а только ссылка на старое содержимое. Чтобы при присваивании создать копию исходного массива, можно воспользоваться функцией Copy:
B := Copy(A);
где A – переменная, ссылающаяся на существующий в памяти динамический массив, B – переменная того же типа, которая после выполнения указанной операции будет ссылаться на копию исходного массива. Вторым вариантом является копирование в новую переменную ссылки на исходный массив и последующий вызов функции изменения размера массива для этой новой переменной:
B := A;
System.SetLength(B, System.Length(B));
В результате выполнения этих операций встроенный в Delphi механизм управления памятью разделит ссылки A и B, создав для B копию исходного динамического массива.
Следует отметить, что при организации математических вычислений на Delphi для работы с действительными числами рекомендуется всегда использовать тип Extended, обеспечивающий повышенную точность вычислений на платформе x86 за счёт представления в памяти в виде 10 байт (80 бит), в отличие от типов Float или Double, число байт для которых меньше (4 и 8 соответственно). На платформе x64 из соображений совместимости тип Extended является синонимом для типа Double, т.е. занимает 8 байт вместо 10. При этом на платформе x86 разрядность 80 бит для арифметических операций поддерживается на аппаратном уровне (процессором), т.е. является естественной для представления действительных чисел.
Объединение описанного способа хранения данных с реализацией вычислительных операций над векторами, матрицами и кватернионами удобно сделать с использованием объектно-ориентированного подхода. Ниже рассматриваются два возможных варианта такой реализации – на основе записей (record) и классов (class). Каждый из этих вариантов имеет свои преимущества и недостатки, которые следует учитывать при выборе одного из них для практического использования.
