Spec-Zone.ru › Ada 2022
Руководство по Ada (Ada 2022)

7.5 Ограниченные типы

Ограниченный тип — это (вид) тип, для которого копирование (например, для оператора присваивания assignment_statement) запрещено. Неограниченный тип — это (вид) тип, для которого копирование разрешено.

Правила легальности

Если помеченный тип записи имеет какие-либо ограниченные компоненты, то ключевое слово limited должно присутствовать в его record_type_definition. Если ключевое слово limited появляется в определении derived_type_definition, его родительский тип и все интерфейсы предков должны быть ограниченными.
В следующих контекстах выражение expression ограниченного типа допускается только если каждый его оперативный компонент создается заново (см. 4.4):
  • выражение инициализации expression объявления объекта object_declaration (см. 3.3.1)
  • выражение по умолчанию default_expression объявления компонента component_declaration (см. 3.8)
  • выражение expression ассоциации компонента записи record_component_association (см. 4.3.1)
  • выражение expression части предка ancestor_part агрегата расширения extension_aggregate (см. 4.3.2)
  • выражение expression позиционного агрегата массива positional_array_aggregate или выражение expression ассоциации компонента массива array_component_association (см. 4.3.3)
  • базовое выражение expression агрегата record_delta_aggregate (см. 4.3.4)
  • выражение qualified_expression инициализированного аллокатора (см. 4.8)
  • выражение expression оператора возврата (см. 6.5)
  • выражение возврата функции выражения (см. 6.8)
  • выражение default_expression или фактический параметр для формального объекта с режимом in (см. 12.4)

Статическая семантика

Вид типа является ограниченным, если он относится к одному из следующих:
  • тип с ключевым словом limited, synchronized, task или protected в его определении;
  • классовый тип, чьей конкретный тип ограничен;
  • составной тип с ограниченным компонентом;
  • неполный вид;
  • производный тип, родитель которого ограничен и не является интерфейсом.
В противном случае, тип неограничен.
Для ограниченного типа нет предопределенных операторов равенства.
Тип является неизменно ограниченным, если он относится к одному из следующих:
  • Явно ограниченный тип записи;
  • Расширение записи с ключевым словом limited;
  • Неформальный ограниченный тип-приват, который является помеченным или имеет по крайней мере один дискриминант доступа с default_expression;
  • Тип задачи, защищённый тип или синхронизированный интерфейс;
  • Тип, производный от неизменно ограниченного типа.
Потомок формального ограниченного типа-приват является, предположительно, неизменно ограниченным, за исключением тела генерируемого модуля или тела, объявленного в области объявления генерируемого модуля, если формальный тип объявлен в формальной части генерируемого модуля.
ПРИМЕЧАНИЕ 1 Хотя разрешается писать инициализации ограниченных объектов, такие инициализации никогда не копируют ограниченный объект. Источником такой операции присваивания будет aggregate или function_call, и такие aggregates и function_calls будут построены непосредственно в целевом объекте (см. 7.6).
Абзацы с 10 по 15 были удалены.
ПРИМЕЧАНИЕ 2 Как показано в 7.3.1, неопределённый ограниченный тип может стать неограниченным при определённых обстоятельствах.

Примеры

Пример пакета с ограниченным типом:
package IO_Package is
type File_Name is limited private;
procedure Open (F : in out File_Name);
procedure Close(F : in out File_Name);
procedure Read (F : in File_Name; Item : out Integer);
procedure Write(F : in File_Name; Item : in Integer);
private
type File_Name is
limited record
Internal_Name : Integer := 0;
end record;
end IO_Package;
package body IO_Package is
Limit : constant := 200;
type File_Descriptor is record ... end record;
Directory : array (1 .. Limit) of File_Descriptor;
...
procedure Open (F : in out File_Name) is ... end;
procedure Close(F : in out File_Name) is ... end;
procedure Read (F : in File_Name; Item : out Integer) is ... end;
procedure Write(F : in File_Name; Item : in Integer) is ... end;
begin
...
end IO_Package;
В примере внешняя подпрограмма, использующая IO_Package, может получить имя файла, вызвав Open, и впоследствии использовать его в вызовах Read и Write. Таким образом, вне пакета имя файла, полученное из Open, действует как своего рода пароль; его внутренние свойства (например, содержащее числовое значение) неизвестны, и над именем файла нельзя выполнять другие операции (например, сложение или сравнение внутренних имён). Важнее всего, что клиенты пакета не могут создавать копии объектов типа File_Name.
Этот пример характерен для любого случая, когда требуется полный контроль над операциями типа. Такие пакеты служат двойной цели. Они предотвращают использование пользователем внутренней структуры типа. Они также реализуют понятие инкапсулированного типа данных, где единственными операциями над типом являются те, которые заданы в спецификации пакета.
Тот факт, что полный вид File_Name явно объявлен limited, означает, что передача параметров всегда будет по ссылке, а результаты функций всегда будут создаваться непосредственно в результате объекта (см. 6.2 и 6.5).


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API