7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ

Описание типа в качестве личного (приватного) в видимом разделе пакета служит для отделения характеристик, которые могут быть использованы непосредственно внешними программными модулями (логические свойства), от других характеристик, непосредственное использование которых возможно только внутри пакета (детали определения самого типа). Описания субконстант задают константы личных типов.

описание-личного-типа ::=    type идентификатор [раздел-дискриминантов] is [limited] private;описание-субконстанты ::=   список-идентификаторов : constant обозначение-типа;

Описание личного типа допустимо только в качестве элемента описания в видимом разделе пакета или в качестве описания параметра настройки для типа в разделе формальных параметров настройки.

Обозначение типа в описании субконстанты должно обозначать личный тип или подтип личного типа. Описание субконстанты и описание соответствующего личного типа должны быть оба элементами описаний в видимом разделе одного и того же пакета. Описание субконстант с несколькими идентификаторами эквивалентно последовательности описаний субконстант с одним идентификатором, как объяснено в разд. 3.2.

Примеры описаний личного типа:

type KEY is private;type FILENAME is limited private;

Пример описания субконстанты:

NULLKEY : constant KEY;

Ссылки: видимый раздел 7.2, идентификатор 2.3, константа 3.2.1, лимитируемый тип 7.4.4, личный тип 7.4.1, обозначение типа 3.3.2, описание 3.1, описание параметра настройки 12.1, пакет 7, подтип 3.3, программный модуль 6, раздел дискриминанта 3.7.1, раздел формальных параметров настройки 12.1, список идентификаторов 3.2, тип 3.3, формальный тип настройки 12.1, элемент описания 3.9.

7.4.1. ЛИЧНЫЕ ТИПЫ

Если описание личного типа дается в видимом разделе пакета, то соответствующее описание типа с тем же самым идентификатором должно присутствовать в качестве элемента описания в личном разделе пакета. Соответствующее описание должно быть либо полным описанием типа, либо описанием задачного типа. В оставшейся части этого раздела объяснения даются для полных описаний типов. Те же правила применяются к описаниям задачных типов.

Описание личного типа и соответствующее полное описание типа определяют один тип. Описание личного типа вместе с видимым разделом определяет операции, которые могут использовать внешние программные модули (см. 7.4.2). С другой стороны, полное описание типа определяет другие операции, непосредственное использование которых возможно только внутри самого пакета.

Если описание личного типа включает раздел дискриминантов, то полное описание типа должно включать раздел дискриминантов по правилам согласования (см. 6.3.1) и определением типа должно быть определение именуемого типа. И наоборот, если описание личного типа не включает раздела дискриминантов, то тип, описанный с помощью полного описания типа {полный тип), не должен быть неограниченным типом с дискриминантами. Полный тип не должен быть неограниченным индексируемым типом. Лимитируемый тип (в частности, задач-ный тип) допускается в качестве полного типа, только если в описании личного типа присутствует зарезервированное слово limited (см. 7.4.4).

Внутри спецификации пакета, в которой описан личный тип, и до конца соответствующего полного описания типа ограничено использование имени этого личного типа или его подтипа, а также использование имени любого типа или подтипа с подкомпонентой данного личного типа. Использование такого имени допускается только в описании субконстанты, описаниитипа или подтипа, спецификации подпрограммы или описания входа; более того, не допускается использование этого имени в определениях производного типа или в простых выражениях.

При предвыполнении описания личного типа создается личный тип. Если описание личного типа имеет раздел дискриминантов, то он также предвыполняется. Предвыполнение полного описания типа заключается в предвыполнении определения типа; если имеется раздел дискриминантов, то он не предвыполняется (так как уже предвыполнен согласованный раздел дискриминантов в описании личного типа).

Примечание. Из перечисленных правил следует, что ни описание переменной личного типа, ни создание объекта личного типа с помощью генератора недопустимо до полного описания типа. Точно также до полного описания нельзя использовать имя личного типа в конкретизации настройки или в спецификаторе представления.

Ссылки: видимый раздел 7.2, выражение 4.4, генератор 4.8, зарезервированное слово 2.9, идентификатор 2.3, имя 4.1, индексируемый тип 3.6, конкретизация настройки 12.3, лимитируемый тип 7.4.4, личный раздел 7.2, личный тип 7.4, неограниченный индексируемый тип 3.6, неполное описание типа 3.8.1, операция 3.3, описание входа 9.5, описание личного типа 7.4, описание подтипа 3.3.2, описание субконстанты 7.4.3, описание типа 3.3.1, определение именуемого типа 3.7, определение типа 3.3.1, пакет 7, переменная 3.2.1, подкомпонента 3.3, подтип 3.3, полное описание типа 3.3.1, Предвыполнение 3.9, производный тип 3.4, раздел дискриминанта 3.7.1, согласованный 6.3.1, спецификатор представления 13.1, спецификация пакета 7.1, спецификация подпрограммы 6.1, тип 3.3, элемент описания 3.9.

7.4.2. ОПЕРАЦИИ НАД ЛИЧНЫМ ТИПОМ

Операции, которые неявно описаны введением описания личного типа, включают базовые операции: присваивание (кроме лимитируемого типа), проверку принадлежности, квалификацию, явное преобразование и именование компоненты для какого-либо дискриминанта. минанта.

Для личного типа Т в базовые операции также входят атрибуты Т'BASE (см. 3.3.3) и T'SIZE (см. 13.7.2). Для объекта А личного типа в базовые операции включается атрибут A'CONSTRAINED, если личный тип содержит дискриминант (см. 3.7.4), и во всех случаях — атрибуты A'SIZE и A'ADDRESS (см. 13.7.2).

Наконец, операции, неявно описанные описанием личного типа, включают предопределенные отношения равенства и неравенства (кроме личных типов, в описании которых присутствует зарезервированное слово limited).

Рассмотренные выше операции вместе с подпрограммами, которые имеют параметр или результат личного типа и описаны в видимом разделе пакета, являются единственными операциями над .личным типом, используемыми вне пакета.

Внутри пакета, содержащего описание личного типа, дополнительные операции вводятся неявно полным описанием типа. При этом переопределение этих операций допустимо внутри той же самой зоны описаний, а именно между описанием личного типа и соответствующим полным описанием. Явно описанная подпрограмма скрывает неявно описанную операцию, которая имеет тот же самый профиль типа параметров и результата (это возможно, только если неявно описанной операцией является производная подпрограмма или предопределенная операция).

Если составной тип имеет подкомпоненту личного типа и описан вне пакета, содержащего описание личного типа, то неявно описанные при описании составного типа операции включают все операции, зависящие только от характеристик, вытекающих из одного описания личного типа. (Например, операция < не включается в набор операций для одномерного индексируемого типа.)

Если составной тип сам описан внутри пакета, содержащего описание личного типа (включая внутренний пакет или настраиваемый пакет), то неявно описываются дополнительные операции, которые зависят от характеристик полного типа, как этого требуют правила использования составного типа (например, операция < описана для одномерного индексируемого типа, если полный тип является дискретным). Эти дополнительные операции считаются неявно описанными в самом начале непосредственной области действия составного типа, их использование разрешено только после полного описания типа.

Те же правила относятся к неявно описанным для ссылочного типа операциям, чье обозначение типа есть личный тип или тип, описанный посредством неполного описания типа.

Для каждого личного типа или полтипа Т определен следующий атрибут:

T'CONSTRAINED

Вырабатывает значение FALSE, если Т обозначает неограниченный неформальный личный тип с дискриминантами, не являющийся формальным параметром настройки; вырабатывает также значения FALSE, если Т обозначает личный тип, являющийся формальным параметром настройки, а соответствующий подтип фактического параметра является либо неограниченным типом с дискриминантом, либо неограниченным индексируемым типом; в остальных случаях вырабатывает значение TRUE. Значение атрибута имеет предопределенный тип BOOLEAN.

Примечание. Описание личного типа и соответствующее полное описание типа определяют два разных аспекта одного и того же типа. Вне пакета тип обладает теми характеристиками которые определены в видимой части. Для внешних программных модулей тип является именно личным типом, и любое правило языка, которое применяется только к другому классу типов к этому типу неприменимо. Тот факт, что полное описание может реализовать личный тип в виде типа конкретного класса (например, в виде индексируемого типа), можно использовать только внутри пакета.

Последствия такой фактической реализации сказываются тем не менее везде. Например, производится некоторая инициализация компонент по умолчанию; атрибут SIZE вырабатывает раз'мер полного типа; правила зависимости задач распространяются также на компоненты — объекты задачного типа.

Пример:

package KEY_MANAGER is   type KEY is private;   NULL_KEY : constant KEY;   procedure GET_KEY(K : out KEY);   function "<" (X, Y : KEY) return BOOLEAN:private   type KEY is new NATURAL:   NULLKEY : constant KEY := 0;end;package body KEY_MANAGER is    LAST_KEY : KEY := 0;   procedure GET_KEY(K : out KEY) is   begin      LAST_KEY := LAST_KEY + 1;      К := LAST_KEY;   end GET_KEY;   function "<" (X. Y : KEY) return BOOLEAN is   begin      return INTEGER(X) < INTEGER(Y);   end "<";end KEY_MANAGER;

Примечание к примеру: Операциями, применимыми к объектам типа KEY вне пакета KEY MANAGER являются: присваивание, сравнение на равенство и неравенство, процедура GET_KEY и операция "<"; сюда не включаются другие операции отношения, например >=или арифметические операции.

Явно описанная операция " <" скрывает предопределенную операцию < , неявно опи_ санную полным описанием типа. В теле функции необходимо явное преобразование Х и Y к типу INTEGER для явного вызова операции "<" над этим типом. С другой стороны результат функции мог бы быть записан в виде not(X > = Y), так как операция " > = не переопре-

Значение переменной LAST_KEY, описанной в теле пакета, не меняется между вызовами процедуры GET_KEY (см. также примечание к разд. 7.3).

Ссылки- атрибут 4.1.4, базовая операция 3.3.3, видимый раздел 7.2, дискриминант 3.3, зависимость задач 9.4, именованная компонента 4.1.3, квалификация 4.7, компонента 3.3, контроль принадлежности 4.5, личный тип 7.4, неполное описание типа 3.8.1, непосредственная областьдействия 8.2, неявное описание 3.1, область описания 8.1, основная операция 3.3.3, операция 3.3, операция отношения 4.5, описание 3.1, описание личного типа 7.4, пакет 7, параметр подпрограммы 6.2, подпрограмма 6, полное описание типа 3.3.1, полный тип 7.4.1, предопределенная операция 4.5, предопределенная функция 8.6, преобразование 4.6, присваивание 5.2, программный модуль 6, производная подпрограмма 3.4, производный тип 3.4, равенство 4.5.2, размерность 3.6, скрытие 8.3, составной тип 3.3.

7.4.3. СУБКОНСТАНТЫ

Если описание субконстанты дается в видимом разделе пакета, то описание константы (т. е. описание объекта, задающее константу с явной инициализацией) с тем же самым идентификатором должно быть элементом описания личного раздела этого пакета. Такое описание объекта называется полным описанием субконстанты. Заданное в полном описании обозначение типа должно быть согласовано с обозначением типа, заданным в описании субконстанты (см. 6.3.1). Допускаются групповые и единичные полные описания и описания субконстант при условии, что эквивалентные единичные описания согласованы.

В спецификации пакета, содержащей описание субконстанты, и до конца соответствующего полного описания имя субконстанты допускается использовать только в выражении по умолчанию для именуемой компоненты или формального параметра (но не формального параметра настройки).

Предвыполнение описания субконстанты не дает другого эффекта.

Выполнение программы ошибочно, если оно пытается использовать значение субконстанты до предвыполнения соответствующего полного описания.

Примечание. Полное описание субконстанты заданного личного типа не должно встречаться до соответствующего полного описания типа. Это является следствием правил, определяющих допустимые использования имени, обозначающего личный тип (см. 7.4.1).

Ссыпки: видимый раздел 7.2, выражение по умолчанию для дискриминанта 3.7.1, идентификатор 2.3, именуемая компонента 3.7, личный раздел 7.2, обозначение типа 3.3.2, описание константы 3.2.1, описание объекта 3.2.1, описание субконстанты 7.4, пакет 7, Предвыполнение не дает другого эффекта 3.1, согласованный 6.3.1, спецификация пакета 7.1, субконстанта 7.4, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3, элемент описания 3.9.

7.4.4. ЛИМИТИРУЕМЫЕ ТИПЫ

Лимитируемый тип — это тип, для которого неявным описанием не вводится ни присваивание, ни сравнение на равенство и неравенство.

Описание личного типа с зарезервированным словом limited описывает лимитируемый тип. Задачный тип является лимитируемым типом. Производный тип от лимитируемого типа сам является лимитируемым типом. Наконец, составной тип является лимитируемым, если тип одной из его компонент является лимитируемым.

Над личным лимитируемым типом определены операции, которые даны в разд. 7.4.2, за исключением присваивания и предопределенного сравнения на равенство и неравенство.

Вид out допустим для формального параметра лимитируемого типа, описанного явно, только в том случае, если этот тип является личным лимитируемым типом, а описание подпрограммы находится в видимом разделе пакета, где описан и личный тип. То же самое относится к формальным параметрам описаний входов и описаний настраиваемых процедур. Соответствующий полный тип не должен быть лимитируемым, если любой такой формальный параметр имеет вид out. В противном случае в качестве соответствующего полного типа допускается (но не требуется) лимитируемый тип (в частности, допустив^задачный тип). Если полный тип, соответствующий лимитируемому личному типу, сам не является лимитируемым, то для этого типа в пакете (но не вне его) допустимо присваивание.

Из правил для лимитируемых типов вытекает следующее:

• Если тип объекта является лимитируемым, то в описании этого объекта явная инициализация недопустима.

• Если тип именуемой компоненты является лимитируемым, то выражение по умолчанию в описании компоненты недопустимо.

• Если тип объекта, указанного ссылочным типом, является лимитируемым, то в генераторе явная инициализация недопустима.

• Формальный параметр настройки вида in не должен быть лимитируемого типа. Примечание. Описанные выше правила не исключают выражение по умолчанию для формального параметра лимитируемого типа; они не исключают также субконстанту лимитируемого типа, если полный тип не является лимитируемым. Для лимитируемого типа допускается явное описание операции равенства (см. 6.7).

Для лимитируемого составного типа не разрешаются агрегаты (см. 3.6.2 и 3.7.4). Для лимитируемого индексируемого типа не разрешается катенация (см. 3.6.2).

Пример:

package I_O_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      record         INTERNAL_NAME : INTEGER := 0;      end record;end I_0_PACKAGE;package body I_0_PACKAGE is    LIMIT : constant := 200;   type FILE_DESCRIPTOR is record ... end record;   DIRECTORY : array (1 .. LIMIT) of P1LE_DESCRIPTOR;   ...   procedure OPEN (F   in out FILE_NAME) is ... end;   procedure CLOSE (F   in out FILEJMAME) Is ... end;   procedure READ (F  in FILE_NAME; ITEM : out INTEGER) is ... end:   procedure WRITE (F  in FILEJMAME; ITEM : in   INTEGER) Is ... end;begin   ...end I_O_PACKAGE;

Примечание к примеру. В приведенном примере для внешних подпрограмм, использующих !_ О-PACKAGE, имя файла можно получить в результате вызова процедуры OPEN, а затем использовать его в вызовах процедур READ и WRITE. Следовательно, вне пакета имя файла, полученное после вызова процедуры OPEN, выполняет функцию пароля; его внутренние свойства (например, содержать числовое значение) неизвестны, и никакие другие операции (такие как сложение или сравнение внутренних имен) над этим именем не могут выполняться.

Этот пример характерен для тех случаев, когда желателен полный контроль над операциями. Такие пакеты служат двум целям: они препятствуют пользователю в использовании внутренней структуры типа, а также реализуют понятие упрятывания (скрытия) типа данных, для которых определены только заданные в спецификации пакета операции.

Ссылки: агрегат 4.3, вид 12.1.1, выражение по умолчанию для дискриминанта 3.7, генератор 4.8, задачный тип 9.1, 9.2, именуемая компонента 3.7, именуемый тип 3.7, личный тип 7.4, начальное значение 3.2.1, неявное описание 3.1, обозначает 3.8, объект 3.2, операция 3.3, операция катенации 4.5, операция отношения 4.5, описание компоненты 3.7, описание личного типа7.4. пакет 7, подкомпонента 3.3, подпрограмма 6, полное описание типа 3.3.1, полный тип 7.4.1, предопределенная операция 4.5, присваивание 5.2, производный тип 3.4, равенство 4.5.2, составной тип 3.3, спецификация дискриминанта 3.7.1, субконстанта 7.4.3, тип 3.3, тип компоненты 3.3, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3.