Справочник Ada 2012
3.10 Типы доступа
Значение типа доступа (значение доступа) предоставляет косвенный доступ к объекту или подпрограмме, которое оно обозначает. В зависимости от его типа, значение доступа может обозначать подпрограммы, объекты, созданные аллокаторами (см. 4.8), или более общие алиасированные объекты соответствующего типа.
Синтаксис
access_type_definition ::=
[null_exclusion] access_to_object_definition
| [null_exclusion] access_to_subprogram_definition
[null_exclusion] access_to_object_definition
| [null_exclusion] access_to_subprogram_definition
general_access_modifier ::= all | constant
access_to_subprogram_definition ::=
access [protected] procedure parameter_profile
| access [protected] function parameter_and_result_profile
access [protected] procedure parameter_profile
| access [protected] function parameter_and_result_profile
null_exclusion ::= not null
access_definition ::=
[null_exclusion] access [constant] subtype_mark
| [null_exclusion] access [protected] procedure parameter_profile
| [null_exclusion] access [protected] function parameter_and_result_profile
[null_exclusion] access [constant] subtype_mark
| [null_exclusion] access [protected] procedure parameter_profile
| [null_exclusion] access [protected] function parameter_and_result_profile
Статическая семантика
Существуют два типа доступа: доступ к объекту, значения которого обозначают объекты, и доступ к подпрограмме, значения которого обозначают подпрограммы. С типом доступа к объекту связан пул памяти; несколько типов доступа могут использовать один и тот же пул памяти. Все потомки типа доступа используют один и тот же пул памяти. Пул памяти — это область памяти, используемая для хранения динамически выделенных объектов (называемых элементами пула), созданных аллокаторами; пулы памяти подробно описаны в 13.11, «Управление памятью».
Типы доступа к объекту подразделяются на специфичные для пула типы доступа, значения которых могут обозначать только элементы своего связанного пула памяти, и общие типы доступа, значения которых могут обозначать элементы любого пула памяти, а также алиасированные объекты, созданные объявлениями, а не аллокаторами, и алиасированные подкомпоненты других объектов.
Вид объекта определяется как алиасированный, если он определяется объявлением объекта (object_declaration), определением компонента (component_definition), спецификацией параметра (parameter_specification) или объявлением расширенного возвращаемого объекта (extended_return_object_declaration) со служебным словом aliased, или путём переименования алиасированного вида. Кроме того, обращение к значению доступа к объекту обозначает алиасированный вид, как и преобразование вида (см. 4.6) алиасированного вида. Текущий экземпляр неизменяемого ограниченного типа (см. 7.5) определяется как алиасированный. Наконец, формальный параметр или формальный объект-обобщение помеченного типа определяются как алиасированные. Алиасированные виды — это те, которые могут быть обозначены значением доступа.
Определение доступа к объекту (access_to_object_definition) определяет тип доступа к объекту и его первый подтип; subtype_indication определяет подтип, обозначаемый типом доступа. Если появляется general_access_modifier, то тип доступа является общим типом доступа. Если модификатор — служебное слово constant, то тип является типом доступа к константе; обозначенный объект не может быть обновлён через значение такого типа. Если модификатор — служебное слово all, то тип является типом доступа к переменной; обозначенный объект может быть как прочитан, так и обновлён через значение такого типа. Если general_access_modifier не указан в access_to_object_definition, тип доступа является специфичным для пула типом доступа к переменной.
Определение доступа к подпрограмме (access_to_subprogram_definition) определяет тип доступа к подпрограмме и его первый подтип; parameter_profile или parameter_and_result_profile определяет обозначаемый профиль типа доступа. С обозначенным профилем связан метод вызова; подпрограммы только с этим методом вызова могут быть обозначены значениями типа доступа. По умолчанию, метод вызова — «защищённый», если указано служебное слово protected, и «Ada» в противном случае. См. Приложение B, как переопределить этот параметр.
Определение доступа (access_definition) определяет анонимный общий тип доступа или анонимный тип доступа к подпрограмме. Для общего типа доступа subtype_mark обозначает его подтип, обозначаемый типом доступа; если general_access_modifier constant указано, тип является типом доступа к константе; в противном случае — типом доступа к переменной. Для типа доступа к подпрограмме parameter_profile или parameter_and_result_profile обозначает его обозначаемый профиль.
Для каждого типа доступа существует нулевое значение доступа, не обозначающее ни одного объекта, которое можно получить (неявно) преобразованием литерала null в тип доступа. Нулевое значение типа доступа является значением по умолчанию для инициализации типа. Не нулевые значения типа доступа к объекту получаются путём вычисления allocator, который возвращает значение доступа, обозначающее недавно созданный объект (см. 3.10.2), или в случае общего типа доступа к объекту, вычислением attribute_reference для атрибута Access или Unchecked_Access алиасированного вида объекта. Не нулевые значения типа доступа к подпрограмме получаются путём вычисления attribute_reference для атрибута Access неинтринсичной подпрограммы.
null_exclusion в конструкции указывает, что нулевое значение не относится к подтипу доступа, определяемому конструкцией, то есть подтип доступа исключает null. Кроме того, анонимный подтип доступа, определённый access_definition для управляющего параметра доступа (см. 3.9.2) исключает null. Наконец, для subtype_indication без null_exclusion, подтип, обозначаемый subtype_indication, исключает null тогда и только тогда, когда подтип, обозначаемый subtype_mark в subtype_indication исключает null.
Все подтипы типа доступа к подпрограмме ограничены. Первый подтип типа, определённый access_definition или access_to_object_definition, является неограниченным, если подтип, обозначаемый типом, является неограниченным массивом или дискриминированным подтипом; в противном случае — ограничен.
Правила легальности
Если subtype_indication, discriminant_specification, parameter_specification, parameter_and_result_profile, object_renaming_declaration или formal_object_declaration содержит null_exclusion, то subtype_mark в данной конструкции должен обозначать подтип доступа, который не исключает null.
Динамическая семантика
Композиционное ограничение composite_constraint совместимо с неограниченным типом доступа, если оно совместимо с назначенным типом. Ограничение исключения нулевого значения null_exclusion совместимо с любым типом доступа, который не исключает null. Значение типа доступа удовлетворяет композиционному ограничению composite_constraint типа доступа, если оно равно нулевому значению его типа или если оно обозначает объект, значение которого удовлетворяет ограничению. Значение типа доступа удовлетворяет исключению нулевого значения, если оно не равно нулевому значению его типа.
Разработка определения типа доступа access_type_definition создаёт тип доступа и его первый подтип. Для типа доступа к объекту эта разработка включает разработку указания подтипа subtype_indication, которая создаёт назначенный подтип.
Разработка определения доступа access_definition создаёт анонимный тип доступа.
ПРИМЕЧАНИЯ
86 Значения типов доступа в некоторых других языках называются «указателями» или «ссылками».
87 Каждый тип доступа к объекту имеет связанный пул памяти; несколько типов доступа могут использовать один и тот же пул. Объект может быть создан в пуле памяти типа доступа с помощью оператора выделения allocator (см. 4.8) для типа доступа. Пул памяти (приблизительно) соответствует тому, что в некоторых других языках называют «кучей». См. 13.11 для обсуждения пулов.
88 Только ограничения индексов index_constraint и ограничения дискриминант discriminant_constraint могут применяться к типам доступа (см. 3.6.1 и 3.7.1).
Примеры
Примеры типов доступа к объектам:
тип Frame является доступом Matrix; -- см. 3.6
тип Peripheral_Ref не является нулевым доступом Peripheral; -- см. 3.8.1
тип Binop_Ptr является доступом ко всем Binary_Operation'Class;
-- общий доступ к всему классу, см. 3.9.1
тип Peripheral_Ref не является нулевым доступом Peripheral; -- см. 3.8.1
тип Binop_Ptr является доступом ко всем Binary_Operation'Class;
-- общий доступ к всему классу, см. 3.9.1
Пример подтипа доступа:
подтип Drum_Ref является Peripheral_Ref(Drum); -- см. 3.8.1
Пример типа доступа к подпрограмме:
тип Message_Procedure является доступом к процедуре (M : входной String := "Error!");
процедура Default_Message_Procedure(M : входной String);
Give_Message : Message_Procedure := Default_Message_Procedure'Access;
...
процедура Other_Procedure(M : входной String);
...
Give_Message := Other_Procedure'Access;
...
Give_Message("Файл не найден."); -- вызов с параметром (.all необязательно)
Give_Message.all; -- вызов без параметров
процедура Default_Message_Procedure(M : входной String);
Give_Message : Message_Procedure := Default_Message_Procedure'Access;
...
процедура Other_Procedure(M : входной String);
...
Give_Message := Other_Procedure'Access;
...
Give_Message("Файл не найден."); -- вызов с параметром (.all необязательно)
Give_Message.all; -- вызов без параметров