Циклические ссылки модулей - это ситуация, которая возникает при одновременном подключении двумя или несколькими модулями друг друга. В случае взаимных ссылок между двумя модулей возникают прямые циклические ссылки. Если же три или более модуля ссылаются друг на друга (см. рисунок ниже) то возникают косвенные циклические ссылки.

mo2

Например:

Пусть нам требуется автоматизировать вывод сообщений и информацию об ошибках. Создадим для этого два модуля.

Процедуры модуля Display позволяют выводить на экран информацию об ошибках и сообщения, содержимое которых находится в модуле MSConst.

Модуль MSConst содержит два константных строковых массива с информацией об ошибках и сообщениями, а также процедуру, объединяющую в себе возможности процедур модуля Display с проверкой на корректность передаваемого аргумента.

Таким образом, оба модуля ссылаются друг на друга.

Модуль Display:

unit Display;

interface

procedure DisplayError(Num:integer);

procedure DisplayMessage(Num:integer);

implementation

uses msconst; { циклическая ссылка на модуль msconst }

procedure DisplayError(Num:integer);

{Процедура DisplayError выводит на экран информацию об ошибке по ее номеру, предваряя словом 'Ошибка!'}

begin writeln('Ошибка! ',Errors[Num]); end;

procedure DisplayMessage(Num:integer);

{Процедура DisplayMessage выводит на экран сообщение по его номеру, предваряя словом 'Сообщение:'}

begin writeln('Сообщение: ',Messages[Num]); end;

end.

Модуль MSConst:

unit MSConst;

interface

const Errors:array[1..3]of string=

('Неправильное выражение',

'Неверный вызов функции',

'Неверный номер сообщения');

const Messages:array[4..6]of string=

('Программа работает нормально',

'Программа начала работу',

'Программа закончила работу');

procedure ShowInfo(Num:integer);

implementation

uses display; { циклическая ссылка на модуль display }

procedure ShowInfo(Num:integer);

{Процедура ShowInfo вызывает процедуры DisplayError и
DisplayMessage
из модуля Display, которые, в свою очередь, используют содержимое массивов из модуля MSConst.}

begin

if Num in [low(Errors)..high(Errors)] then DisplayError(Num)

else

if Num in [low(Messages)..high(Messages)] then DisplayMessage(Num)

else DisplayError(high(Errors));

end;

end.

Основная программа, используемая для проверки возможностей созданных процедур:

uses msConst;

begin

ShowInfo(1);

ShowInfo(4);

ShowInfo(8);

readln;

end.

В результате выполнения программы на экране появятся 3 строки:

Ошибка! Неправильное выражение

Сообщение: Программа работает нормально

Ошибка! Неверный номер сообщения

Основная проблема, возникающая при использовании циклических ссылок, состоит в том, что компилятор не может транслировать модули, если циклические ссылки находятся в интерфейсной части. Например, если в модуле А встречается подключение модулей В и С, то сначала происходит их компиляция, и только затем - докомпиляция модуля А. Если при этом в модулях В или С встретится ссылка на модуль А, возникнет проблема, разрешить которую ТП не в состоянии. Действительно, для компиляции модуля А требуется сначала скомпилировать В и С, которые, в свою очередь требуют компиляции модуля А, который без В и С скомпилирован быть не может. Для выхода из данной ситуации ТП при подготовке программы загружает и обрабатывает одну за другой все интерфейсные секции модулей программы, и только по завершении - секции реализации. Таким образом, циклические ссылки запрещены только в интерфейсной части модуля, в секции же реализации ограничения на них отсутствуют.

Если бы при реализации модулей MSConst и Display мы воспользовались циклическими ссылками в интерфейсной секции, откомпилировать бы программу нам не удалось.


<- Предыдущая страница | Следующая страница ->

Последнее изменение: Вторник 1 Март 2011, 16:36