Справочник Ada 95
7.5 Ограниченные типы
Ограниченный тип — это (вид) тип, для которого операция присваивания запрещена. Неограниченный тип — это (вид) тип, для которого операция присваивания разрешена.
Правила легальности
Если у помеченного типа записи есть какие-либо ограниченные компоненты, то ключевое слово limited должно появляться в его record_type_definition.
Статическая семантика
Тип является ограниченным, если он является потомком одного из следующих:
- типа с ключевым словом limited в его определении;
- задачи или защищенного типа;
- составного типа с ограниченным компонентом.
В противном случае тип является неограниченным.
Для ограниченного типа не определены предопределенные операторы равенства.
ПРИМЕЧАНИЯ
13 Следующие являются следствиями правил для ограниченных типов:
- Выражение инициализации не допускается в object_declaration, если тип объекта ограничен.
- Выражение по умолчанию не допускается в component_declaration, если тип компонента записи ограничен.
- Инициализированный аллокатор не допускается, если назначенный тип ограничен.
- Формальный параметр обобщенного типа с режимом in не должен быть ограниченного типа.
14 Агрегаты недоступны для ограниченного составного типа. Конкатенация недоступна для ограниченного массива.
15 Правила не исключают default_expression для формального параметра ограниченного типа; они не исключают отложенную константу ограниченного типа, если полное объявление константы — неограниченного типа.
16 Как показано в 7.3.1, неопределенный ограниченный тип может стать неограниченным в определенных обстоятельствах.
Примеры
Пример пакета с ограниченным типом:
package IO_Package is
type File_Name is limited private;
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;
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;
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;
ПРИМЕЧАНИЯ
17 Примечания к примеру: В приведенном выше примере внешняя подпрограмма, использующая IO_Package, может получить имя файла, вызвав Open, и позже использовать его в вызовах Read и Write. Таким образом, за пределами пакета имя файла, полученное из Open, действует как своего рода пароль; его внутренние свойства (например, содержащий числовое значение) неизвестны, и другие операции (например, сложение или сравнение внутренних имен) с именем файла не могут выполняться. Самое главное, клиенты пакета не могут создавать копии объектов типа File_Name.
Этот пример характерен для любого случая, где требуется полный контроль над операциями типа. Такие пакеты служат двойной цели. Они предотвращают использование пользователем внутренней структуры типа. Они также реализуют понятие инкапсулированного типа данных, где единственные операции с типом — те, что заданы в спецификации пакета.
Тот факт, что полная форма File_Name явно объявлена как limited, означает, что передача параметров и возврат функции всегда будут по ссылке (см. 6.2 и 6.5).