Руководство по Ada (Ada 2022)
4.1.5 Пользовательские ссылки
Статическая семантика
Учитывая дискриминированный тип T, может быть указан следующий операционный аспект, связанный с типом:
Implicit_Dereference
Этот аспект задаётся именем, обозначающим доступный дискриминант, объявленный для типа T.
Тип (вид типа) со заданным аспектом Implicit_Dereference является ссылочным типом. Объект ссылки — это объект ссылочного типа. Дискриминант, названный аспектом Implicit_Dereference, является дискриминантом ссылки ссылочного типа или объекта ссылки. обобщённая_ссылка — это имя, которое идентифицирует объект ссылки и обозначает объект или подпрограмму, обозначенные дискриминантом ссылки объекта ссылки.
Синтаксис
Правила разрешения имён
Ожидаемый тип для ссылочный_объект_имя в обобщённой_ссылке — это любой ссылочный тип.
Статическая семантика
Аспект Implicit_Dereference является непереопределяемым (см. 13.1.1).
обобщённая_ссылка обозначает вид, эквивалентный виду разыменования дискриминанта ссылки объекта ссылки.
Учитывая ссылочный тип T, аспект Implicit_Dereference наследуется потомками типа T, если не переопределён (что разрешается только в случае подтверждения). Если дочерний тип ограничивает значение дискриминанта ссылки типа T новым дискриминантом, этот новый дискриминант является дискриминантом ссылки потомка. Если дочерний тип ограничивает значение дискриминанта ссылки типа T выражением, отличным от имени нового дискриминанта, обобщённая_ссылка, которая идентифицирует объект дочернего типа, обозначает объект или подпрограмму, обозначенные значением этого ограничивающего выражения.
Динамическая семантика
Вычисление обобщённой_ссылки состоит из вычисления ссылочный_объект_имя и определения объекта или подпрограммы, обозначенной дискриминантом ссылки указанного объекта ссылки. Проводится проверка, что значение дискриминанта ссылки не является нулевым значением доступа. Constraint_Error поднимается, если эта проверка не пройдена. обобщённая_ссылка обозначает объект или подпрограмму, обозначенные значением дискриминанта ссылки указанного объекта ссылки.
Примеры
Примеры спецификации и использования обобщённых ссылок:
type Barrel is tagged ... -- хранит объекты типа Element
type Ref_Element(Data : access Element) is limited private
with Implicit_Dereference => Data;
-- Этот тип Ref_Element является "ссылочным" типом.
-- "Data" является его дискриминантом ссылки.
with Implicit_Dereference => Data;
-- Этот тип Ref_Element является "ссылочным" типом.
-- "Data" является его дискриминантом ссылки.
function Find (B : aliased in out Barrel; Key : String)
return Ref_Element;
-- Возвращает ссылку на элемент бочки.
return Ref_Element;
-- Возвращает ссылку на элемент бочки.
B: aliased Barrel;
...
Find (B, "grape") := Element'(...); -- Присваивание через ссылку.
-- Это эквивалентно:
Find (B, "grape").Data.all := Element'(...);
Find (B, "grape").Data.all := Element'(...);