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

9.4 Защищенные блоки и защищенные объекты

Объект защищенного типа обеспечивает координированный доступ к общим данным через вызовы видимых защищенных операций, которые могут быть защищенными подпрограммами или защищенными входами. Защищённый блок объявляется объявлением защищенного типа, которое имеет соответствующий protected_body. Объявление защищённого типа может быть protected_type_declaration, в этом случае оно объявляет именованный тип защищённого объекта; в альтернативном варианте, это может быть single_protected_declaration, в этом случае оно определяет анонимный тип защищенного объекта и объявляет именованный защищённый объект этого типа.

Синтаксис

protected_type_declaration ::=
protected type defining_identifier [known_discriminant_part]
[aspect_specification] is
[new interface_list with]
protected_definition;
single_protected_declaration ::=
protected defining_identifier
[aspect_specification] is
[new interface_list with]
protected_definition;
protected_definition ::=
{ protected_operation_declaration }
[ private
{ protected_element_declaration } ]
end [protected_identifier]
protected_operation_declaration ::= subprogram_declaration
| entry_declaration
| aspect_clause
protected_element_declaration ::= protected_operation_declaration
| component_declaration
protected_body ::=
protected body defining_identifier
[aspect_specification] is
{ protected_operation_item }
end [protected_identifier];
protected_operation_item ::= subprogram_declaration
| subprogram_body
| null_procedure_declaration
| expression_function_declaration
| entry_body
| aspect_clause
Если protected_identifier появляется в конце protected_definition или protected_body, он должен повторять defining_identifier.
Пункт 10 был удален.

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

Определение protected_definition определяет тип защищенного объекта и его первый подтип. Список protected_operation_declaration в определении protected_definition, вместе с known_discriminant_part, если таковой имеется, называется видимой частью защищенного блока. Необязательный список protected_element_declaration после ключевого слова private называется закрытой частью защищенного блока.
Для объявления защищённого типа с interface_list, тип защищённого объекта наследует пользовательские примитивные подпрограммы из каждого родительского типа (см. 3.9.4), аналогично тому, как производный тип наследует пользовательские примитивные подпрограммы от своих родительских типов (см. 3.4). Если первый параметр унаследованной примитивной подпрограммы имеет тип защищенного объекта или параметр доступа, указывающий на тип защищенного объекта, и существует protected_operation_declaration для защищенной подпрограммы или одного входа с тем же идентификатором внутри объявления защищенного типа, чья сигнатура совместима с префиксным видом сигнатуры унаследованной подпрограммы, то унаследованная подпрограмма считается реализованной соответствующей защищенной подпрограммой или входом с использованием неявно объявленной не абстрактной подпрограммы, имеющей ту же сигнатуру, что и унаследованная подпрограмма и заменяющей её.

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

Объявление защищенного типа требует завершения, которое должно быть protected_body, и каждый protected_body должен быть завершением некоторого объявления защищенного типа.
Каждый interface_subtype_mark в interface_list, появляющемся внутри объявления защищенного типа, должен обозначать ограниченный тип интерфейса, который не является интерфейсом задачи.
Префиксный вид сигнатуры явно объявленной примитивной подпрограммы помеченного защищенного типа не должен быть совместимым по типу с какой-либо защищенной операцией защищенного типа, если подпрограмма имеет то же имя, что и защищенная операция, и первый параметр подпрограммы является типом защищенного объекта или параметром доступа, указывающим на тип защищенного объекта.
Для каждой примитивной подпрограммы, унаследованной типом, объявленным в объявлении защищённого типа, должно выполняться не более одного из следующих условий:
  • унаследованная подпрограмма перезаписывается примитивной подпрограммой защищённого типа, в этом случае переопределяющая подпрограмма должна быть совместимой по типу с унаследованной подпрограммой и не абстрактной; или
  • унаследованная подпрограмма реализуется защищённой подпрограммой или единственным входом защищённого типа, в этом случае её префиксный вид сигнатуры должен быть совместимым по типу с сигнатурой защищённой подпрограммы или входа.
Если ни одно из условий не выполняется, унаследованная подпрограмма должна быть пустой процедурой. В дополнение к местам, где обычно применяются правила легальности (см. 12.3), эти правила также применяются в частях экземпляра обобщённого блока.
Если унаследованная подпрограмма реализуется защищенной процедурой или входом, то первый параметр унаследованной подпрограммы должен быть типа out или in out, или параметром доступа к переменной. Если унаследованная подпрограмма реализуется защищённой функцией, то первый параметр унаследованной подпрограммы должен быть типа in, но не параметром доступа к переменной.
Если объявление защищённой подпрограммы имеет overriding_indicator, то на момент объявления:
  • если overriding_indicator равно overriding, то подпрограмма должна реализовывать унаследованную подпрограмму;
  • если overriding_indicator равно not overriding, то подпрограмма не должна реализовывать ни одну унаследованную подпрограмму.
В дополнение к местам, где обычно применяются правила легальности (см. 12.3), эти правила также применяются в частях экземпляра обобщенного блока.

Динамические семантики

Выполнение объявления защищенного типа выполняет protected_definition. Выполнение single_protected_declaration также создает объект анонимного типа защищённого объекта.
Выполнение protected_definition создаёт тип защищенного объекта и его первый подтип; оно также включает выполнение component_declaration и protected_operation_declaration в указанном порядке.
END_OF_DOCUMENT_MARKER ```
В рамках инициализации защищенного объекта, все ограничения на объект (см. 3.8) детализируются.
Детализация защищенного_тела не имеет других последствий, кроме установления возможности вызова защищенных операций данного типа без сбоя проверки детализации.
Содержание объекта данного защищенного типа включает:
  • Значения компонентов защищенного объекта, включая (в неявном виде) очередь ввода для каждого входа, объявленного для защищенного объекта;
  • Представление состояния ресурса выполнения, связанного с защищенным объектом (такой ресурс ассоциируется с каждым защищенным объектом).
Для чтения или обновления любых компонентов защищенного объекта необходимо получить доступ к ресурсу выполнения, связанному с этим объектом; он может быть получен (как часть защищенного действия — см. 9.5.1) либо для одновременного чтения без записи, либо для исключительного чтения с записью.
В качестве первого шага завершения работы защищенного объекта, каждый вызов, оставшийся в очереди ввода объекта, удаляется из очереди, и возникает ошибка Program_Error в месте соответствующего оператора_вызова_входа.

Ограниченные (временные) ошибки

Вызов входа или подпрограммы защищенного объекта после завершения работы этого объекта является ограниченной ошибкой. Если ошибка обнаружена, то поднимается ошибка Program_Error. В противном случае вызов выполняется нормально, что может привести к тому, что задача будет стоять в очереди бесконечно.
ПРИМЕЧАНИЕ 1 Внутри объявления или тела защищенного блока, кроме определения_доступа, имя защищенного блока обозначает текущий экземпляр блока (см. 8.6), а не первый подтип соответствующего защищенного типа (и, следовательно, имя не может использоваться как метка_подтипа).
ПРИМЕЧАНИЕ 2 выбранный_компонент может использоваться для обозначения дискриминанты защищенного объекта (см. 4.1.3). Внутри защищенного блока имя дискриминанты защищенного типа обозначает соответствующую дискриминанту текущего экземпляра блока.
ПРИМЕЧАНИЕ 3 Защищенный тип — это ограниченный тип (см. 7.5), а это исключает использование оператора_присваивания и предопределенных операторов равенства.
ПРИМЕЧАНИЕ 4 Тела защищенных операций, приведенные в защищенном_теле, определяют действия, выполняемые при вызовах защищенных операций.
ПРИМЕЧАНИЕ 5 Объявления в частной части видимы только внутри частной части и тела защищенного блока.

Примеры

Пример объявления защищенного типа и соответствующего тела:
protected type Resource is
entry Seize;
procedure Release;
private
Busy : Boolean := False;
end Resource;
protected body Resource is
entry Seize when not Busy is
begin
Busy := True;
end Seize;
procedure Release is
begin
Busy := False;
end Release;
end Resource;
Пример одного объявления защищенного блока и соответствующего тела:
protected Shared_Array is
-- Index, Item, and Item_Array are global types
function Component (N : in Index) return Item;
procedure Set_Component(N : in Index; E : in Item);
private
Table : Item_Array(Index) := (others => Null_Item);
end Shared_Array;
protected body Shared_Array is
function Component(N : in Index) return Item is
begin
return Table(N);
end Component;
procedure Set_Component(N : in Index; E : in Item) is
begin
Table(N) := E;
end Set_Component;
end Shared_Array;
Примеры защищенных объектов:
Control : Resource;
Flags : array(1 .. 100) of Resource;


Spec-Zone.ru

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