Ада-95. Компилятор GNAT

       

Настраиваемые подпрограммы


Рассмотрим простой пример описания настраиваемой подпрограммы.

Однажды скомпилированная, она в последствии может быть помещена в инструкцию спецификатора совместности контекста with

в других программных модулях.

Напомним также, что настраиваемый модуль нельзя указывать в инструкции спецификатора использования контекста use.

Спецификация модуля настраиваемой подпрограммы содержит ключевое слово generic, после которого следует список формальных параметров настройки и далее - спецификация процедуры:

generic

type Element is private; -- Element - это параметр настраиваемой -- подпрограммы

procedure Exchange(A, B : in out Element);

Тело настраиваемой процедуры описывает реализацию алгоритма работы процедуры и представляется как отдельно компилируемый модуль. Примечательно, что оно идентично не настраиваемой версии.

procedure Exchange(A, B : in out Element) is



Temp : Element;

begin

T := Temp; T := B; B := Temp; end Exchange;

Код, показанный выше, является простым шаблоном для процедуры, которая может быть реально создана.

Следует обратить внимание на то, что этот код не может быть непосредственно вызван.

Это подобно описанию типа, поскольку не производится никакого распределения пространства памяти или генерации машинного кода.

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

procedure Swap is new Exchange(Integer);

Следует заметить, что в показанном выше примере конкретизация настраиваемой процедуры осуществлена с использованием простого позиционного сопоставления формального и фактического параметров настройки. В дополнение к позиционному сопоставлению, Ада позволяет использовать именное сопоставление формальных и фактических параметров настройки (при большом количестве параметров настройки, именное сопоставление улучшает читабельность). Показанную выше конкретизацию настраиваемой процедуры можно осуществить с помощью использования именного сопоставления следующим образом:




procedure Swap is new Exchange(Element => Integer);

Теперь мы имеем процедуру Swap которая меняет местами переменные целого типа Integer.

Здесь, Integer является фактическим параметром настройки, а Element - формальным параметром настройки.

Процедура Swap может быть вызвана (и она будет вести себя) как будто она была описана следующим образом:

procedure Swap (A, B : in out Integer) is

Temp : Integer;

begin

. . .

end Swap;

Таких процедур Swap можно создать столько, сколько необходимо.

procedure Swap is new Exchange(Character); procedure Swap is new Exchange(Element => Account); -- ассоциация по имени

В этом случае будет нормально использоваться совмещение имен процедур.

Компилятор будет определять к какой конкретно процедуре производится вызов используя информацию о типе параметра.


Содержание раздела