Ссылочные типы для подпрограмм
Также как и обобщенные ссылочные типы, ссылочные типы для подпрограмм не доступны в стандарте Ada83.
Они являются нововведением, которое определил выход стандарта Ada95.
Ссылочные типы для подпрограмм позволяют использовать подпрограммы как параметры передаваемые другим подпрограммам (например, так как это делается в математических библиотеках Фортрана), а также осуществлять позднее связывание.
При описании ссылочных типов для подпрограмм следует придерживаться следующих соглашений:
описание типа должно определять такой список параметров, который соответствует списку параметров подпрограммы на которую будут ссылаться значения этого типа
при описании ссылочного типа для функции, тип возвращаемого значения должен соответствовать типу возвращаемого значения функции на которую будут ссылаться значения этого типа
переменные ссылочного типа для подпрограмм могут быть использованы для доступа к любой подпрограмме профиль которой соответствует профилю определеному при описании этого ссылочного типа
Простейшим примером использования функционального ссылочного типа как параметра подпрограммы может служить следующий фрагмент кода:
type Access_Function is access function(Item: in Float) return Float;
type Vector is array (Integer range < >) of Float; procedure For_Each( F : in Access_Function; To: in out Vector ) is begin for I in To'Range loop To(I) := F( To(I) ); end loop; end For_Each; |
Здесь, процедура For_Each принимает в качестве параметра F
значение ссылочного типа Access_Function указывющее на функцию, которую необходимо вызывать при обработке каждого элемента массива типа Vector, передаваемого ей как параметр To.
Примечательно, что при вызове функции F расшифровка ссылки производится автоматически. Следует также заметить, что вместо "F( To(I) )" можно было бы написать "F.all( To(I) )", что в подобных случаях - не обязательно.
Использование .all требуется когда вызываемая подпрограмма (процедура или функция) не имеет параметров.
Описание переменной массива чисел, передаваемой как параметр To для процедуры For_Each, и описание функции, ссылка на которую могла бы быть использовна как параметр F процедуры For_Each, могут иметь следующий вид:
Data_Vector : Vector (1..3) := (1.0, 2.0, 3.0); function Square(Val: in Float) return Float is begin return Val * Val; end Square; |
For_Each( F => Square'Access, To => Data_Vector ); |
Ссылочные типы для подпрограмм могут быть использованы для построения таблиц вызова подпрограмм. Рассмотрим следующий схематический пример:
type Action_Operation is access procedure; procedure Add; procedure List; procedure Delete; Action : constant array (1..3) of Action_Operation := ( Add'Access, List'Access, Delete'Access ); type Math_Function is access function (I : in Float) return Float; function Sin (F : in Float) return Float; function Cos (F : in Float) return Float; function Tan (F : in Float) return Float; Math_Operation : constant array (1..3) of Math_Function := ( Sin'Access, Cos'Access, Tan'Access ); |
(заметим, что таблицами вызовов, как правило, являются массивы).
Примером вызова I-той подпрограммы в таблице (где I - это индекс в таблице) может служить следующее:
F: Float; . . . Action(I).all; -- вызов I-той процедуры из таблицы -- Action F := Math_Operation(I)(F); -- вызов I-той функции из таблицы -- Math_Operation с параметром F |