Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции програм_new_последняя версия1.doc
Скачиваний:
14
Добавлен:
14.09.2019
Размер:
697.34 Кб
Скачать

Создание класса векторов

Создадим модуль VecMat с описанием класса TVect, в котором реализованы основные операции векторной алгебры. В этом модуле будет использовано основное векторное свойство Property Elem.

При инициализации вектора в динамической памяти выделяют участок, в котором последовательно будут размещены его элементы. Указатель Orig на начало этого участка и методы OutElem и InpElem – для записи и чтения значений элементов определены в секции Private, а значит, будут скрыты. Свойство Property Elem определено в секции Public, а значит доступно в других модулях и программах.

Остановимся подробно на следующем:

  1. Описание метода определения адреса динамической памяти для j-го элемента вектора – метода ElemP.

Метод ElemP позволяет интерпретировать байты памяти, отведенные под элемент с номером j, как значение вещественного типа. Он записывается в секции protected(защищенной), поэтому он доступен потомкам класса TVect.

При описании метода ElemP используются:

  • функция Sizeof(x) – дает размер аргумента x в байтах;

  • функция Ptr(x:integer) – стандартная функция типа указатель, которая преобразует адрес памяти (адрес=сегмент+смещение) в указатель.

function TVect.ElemP;

begin ElemP:=Ptr(LongInt(Orig))+(j – jMin)*Sizeof(Real));

end;

вычисляется как функция Ptr от базового адреса (указатель Orig на начало области динамической памяти + смещение на j – jMin , умноженное на размер каждого элемента в байтах). Для обратного преобразования можно использовать явное приведение типов LongInt (p) – преобразует указатель р в целое число типа LongInt. Для размещения этого целого числа будет отведено 4 байта.

  1. Заметим, что в данном модуле описывается конструктор и деструктор.

а) описание конструктора:

Constructor TVect.Create(jMin_;jMax_:integer);

begin inherited Create;

{вызов унаследованного конструктора от предка}

jMin:=jMin_;

jMax:=jMax_;

GetMem(Orig,(jMax – jMin + 1 )*Sizeof(Real));

Vanish;

end;

процедура GetMem выделяет в динамической памяти область размера (jMax – jMin + 1 )*Sizeof(Real) и присваивает адрес этой области указателю Orig.

Метод Vanish – очищает вектор (создает нулевой вектор)

б) описание деструктора:

Destructor TVect.Destroy;

begin FreeMem(Orig,(jMax – jMin + 1 )*Sizeof(Real));

{освобождает указатель Orig от адреса данной области памяти}

inherited Destroy;

{вызов унаследованного деструктора от предка TObject }

end;

В классе TObject конструктор – это статический метод, а его деструктор – виртуальный метод, поэтому при перекрытии в классе-потомке TVect деструктор описывается с использованием служебного слова override.

  1. Модуль VecMat описывает двухместные операции Add, Sub. Здесь действует соглашение: при выполнении двухместной операции первым операндом является сам объект, вторым операндом – тот, который является формальным параметром метода. Результат сохраняется в полях первого операнда.

Создадим модуль VecMat, в котором описан класс TVect для реализации операций векторной алгебры:

Unit VecMat;

interface // интерфейсная часть

Type Real=extended;

RealP=^Real;

Type TVect=class

Private

Orig:pointer;

{поле Orig используется как указатель адреса динамической области}

Protected

jMin, jMax:integer;{поля –– первый и последний индексы вектора}

{ метод определения адреса j-го элемента вектора}

function ElemP (j:integer):RealP;

Public

{методы для чтения и записи j-го элемента вектора}

function OutElem (j:integer):Real;

procedure InpElem(j:integer;r:Real);

{ конструктор и деструктор }

constructor Create(jMin_,jMax_:integer);

destructor Destroy; override;

{ конструктор – это статический метод, деструктор – виртуальный метод, он перекрыт для динамического замещения в классе- потомке}

property Elem(j:integer):Real read OutElem {свойство}

write InpElem; default;

procedure Vanish; { метод для создания нулевого вектора}

procedure Add(x:TVect); { метод сложения векторов }

procedure Sub(x:TVect); { метод вычитания векторов }

end;

implementation {исполняемая часть }

constructor TVect.Create(jMin_;jMax_:integer);

begin

inherited Create;

{вызов унаследованного конструктора}

jMin:=jMin_;

jMax:=jMax_;

GetMem(Orig,(jMax – jMin + 1 )*Sizeof(Real));

Vanish;

end;

destructor TVect.Destroy;

begin FreeMem(Orig,(jMax – jMin + 1)*Sizeof(Real));

inherited Destroy;

{вызов унаследованного деструктора}

end;

function TVect.ElemP(j:integer):RealP;

begin

ElemP:=Ptr(LongInt(Orig))+(j – jMin)*Sizeof(Real);

end;

Procedure TVect.InpElem(j:integer;r:real);

begin

Elemp(j)^:=r;

{содержимому j-го элемента вектора присвоено значение r}

end;

function TVect.OutElem(j:integer):real;

begin

result:=Elemp(j)^;

{результату присваивается содержимое j-го элемента вектора}

end;

procedure TVect.Vanish;

var j:integer;

begin for j:= jMin to jMax do

ElemP(j)^:=0.0;

end;

procedure TVect.Add(x:TVect); {метод сложения векторов}

var j:integer;

begin for j:=jMin to jMax do

ElemP(j)^:=ElemP(j)^ + x.ElemP(j)^;

end;

procedure TVect.Sub(x:TVect); {метод вычитания векторов}

var j:integer;

begin for j:= jMin to jMax do

ElemP(j)^:=ElemP(j)^ – x.ElemP(j)^;

end;

end. {конец модуля VecMat}

Модуль необходимо сохранить под именем VecMat.pas, затем использовать в других модулях и программах. Напишем программу, которая использует поля, методы и свойства класса TVect из модуля VecMat для конкретных объектов – векторов x и y.

Program Project_Vector;

Uses SysUtils,Dialogs,

VecMat in ‘VecMat.pas’;

var x,y:TVect;

i:integer;

c:real;

begin x:=TVect.Create(1,5);

y:=TVect.Create(1,5);

//конструктор создает вектора из 5 элементов

x.Vanish; //создается нулевой вектор – x

for i:=1 to 5 do

begin

readln(c);

// ввод значений элементов вектора

y.Elem[i]:=c;

// вызов свойства для ввода элементов вектора y

end;

for i:=1 to 5 do

write(y.Elem[i]:4:1,’ ’);

//вызов свойства для вывода элементов вектора y

writeln;

x.Add(y);

//сложение векторов x и y, результат записывается в x

for i:=1 to 5 do

write(x.Elem[i]:4:1,’ ’);

// вызов свойства для вывода элементов вектора x

writeln;

x.Free;

y.Free;

//уничтожение объектов x,y

readln;

End.