Spec-Zone.ru › Ada 2022
Справочник по Ada (Ada 2022)

3.10.1 Неполные объявления типов

Нет особых ограничений на назначенный тип типа доступа. В частности, тип компонента назначенного типа может быть другим типом доступа или даже тем же типом доступа. Это допускает взаимозависимые и рекурсивные типы доступа. Объявление incomplete_type_declaration может использоваться для введения типа, используемого как назначенный тип, откладывая его полное определение на последующее full_type_declaration.

Синтаксис

incomplete_type_declaration ::=
type defining_identifier [discriminant_part] [is tagged];

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

Объявление incomplete_type_declaration объявляет неполный вид типа и его первого подтипа; первый подтип является не ограниченным, если появляется discriminant_part. Если объявление incomplete_type_declaration включает зарезервированное слово tagged, оно объявляет меченый неполный вид. Если T обозначает меченый неполный вид, то T'Class обозначает меченый неполный вид. Неполный вид типа представляет собой ограниченный вид типа (см. 7.5).
В данном случае, для типа доступа A, назначенный тип T которого представляет собой неполный вид, обращение к значению типа A также имеет этот неполный вид, за исключением следующих случаев:
  • если оно находится в непосредственной области завершения T;
  • если оно находится в области nonlimited_with_clause, которая упоминает библиотечный пакет, в видимой части которого объявлено завершение T;
  • если оно находится в области завершения T и T — это неполный вид, объявленный с помощью incomplete_type_declaration.
В этих случаях обращение имеет вид T, видимый в точке обращения.
Аналогично, если subtype_mark обозначает subtype_declaration, определяющую подтип неполного вида T, subtype_mark обозначает неполный вид, за исключением тех же трех случаев, в которых он обозначает вид T, видимый в точке subtype_mark.

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

Объявление incomplete_type_declaration требует завершения, которое должно быть объявлением type_declaration, отличным от incomplete_type_declaration. Если incomplete_type_declaration находится непосредственно в видимой части package_specification или declarative_part, то type_declaration должно произойти позже и непосредственно в этой видимой части или declarative_part. Если incomplete_type_declaration находится непосредственно в частной части данного package_specification, то type_declaration должно произойти позже и непосредственно в самой частной части или в declarative_part соответствующего package_body.
Если incomplete_type_declaration включает зарезервированное слово tagged, то type_declaration, которая его завершает, должна объявлять меченый тип. Если у incomplete_type_declaration есть known_discriminant_part, то type_declaration, которая его завершает, должна иметь полностью соответствующую (явную) known_discriminant_part (см. 6.3.1). Если у incomplete_type_declaration нет discriminant_part (или unknown_discriminant_part), то соответствующее объявление type_declaration все равно может иметь дискриминанты, явно или унаследованные через вывод.
Имя name, обозначающее неполный вид типа, может использоваться следующим образом:
  • как subtype_mark в subtype_indication access_to_object_definition; единственная форма constraint, разрешенная в этой subtype_indication, — это discriminant_constraint (исключение null_exclusion не разрешено);
  • как subtype_mark в subtype_indication объявления subtype_declaration; subtype_indication не должно содержать null_exclusion или constraint;
  • как subtype_mark в access_definition для типа доступа к объекту;
  • как subtype_mark при определении подтипа параметра или результата в профиле, встречающемся в basic_declaration;
  • как фактический параметр обобщения, соответствующий формальному параметру обобщения, который является формальным неполным типом (см. 12.5.1).
Если такое имя name обозначает меченый неполный вид, оно также может использоваться:
  • как subtype_mark при определении подтипа параметра в профиле для subprogram_body, entry_body или accept_statement;
  • как prefix ссылки на атрибут attribute_reference, атрибут attribute_designator которого — Class; такая ссылка на атрибут ограничена разрешенными здесь использованиями; она обозначает меченый неполный вид.
Этот абзац был удалён.
  • Этот абзац был удалён.
Если какое-либо из вышеперечисленных применений используется в качестве части объявления примитивного подпрограммы неполного вида, и объявление находится непосредственно в частной части пакета, то завершение неполного вида также должно находиться непосредственно в частной части; оно не должно откладываться в тело пакета.
Другие применения имени name, которое обозначает неполный вид типа, не допускаются.
Префикс prefix, обозначающий объект, не должен быть неполного вида. Фактический параметр в вызове не должен быть немеченым неполным видом. Результирующий объект вызова функции не должен быть неполного вида. Префикс prefix не должен обозначать подпрограмму с формальным параметром немеченного неполного вида, а также тип возвращаемого значения, который представляет собой неполный вид.
Операнд управления или результат управления вызова диспетчеризации не должны быть неполного вида, если операнд или результат динамически помечены.
Параграф 11 был удалён.

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

Разъяснение неполного_объявления_типа не оказывает никакого эффекта.
ПРИМЕЧАНИЕ 1 Внутри раздела_объявлений, неполное_объявление_типа и соответствующее ему полное_объявление_типа не могут быть разделены промежуточным телом. Это связано с тем, что по правилам, приведенным в 13.14, тип является недопустимым, если он не полностью определен до его замораживания, а тело замораживает все типы, объявленные перед ним в том же разделе_объявлений.
ПРИМЕЧАНИЕ 2 Имя, обозначающее объект неполного представления, определяется как имеющего ограниченный тип. Следовательно, целевой объект оператора присваивания не может иметь неполное представление.

Примеры

Пример рекурсивного типа:
type Cell; -- неполное объявление типа
type Link is access Cell;
type Cell is
record
Value : Integer;
Succ : Link;
Pred : Link;
end record;
Head : Link := new Cell'(0, null, null);
Next : Link := Head.Succ;
Примеры взаимно зависимых типов доступа:
type Person(<>); -- неполное объявление типа
type Car is tagged; -- неполное объявление типа
type Person_Name is access Person;
type Car_Name is access all Car'Class;
type Car is tagged
record
Number : Integer;
Owner : Person_Name;
end record;
type Person(Sex : Gender) is
record
Name : String(1 .. 20);
Birth : Date;
Age : Integer range 0 .. 130;
Vehicle : Car_Name;
case Sex is
when M => Wife : Person_Name(Sex => F);
when F => Husband : Person_Name(Sex => M);
end case;
end record;
My_Car, Your_Car, Next_Car : Car_Name := new Car; -- см. 4.8
Casey : Person_Name := new Person(M);
...
Casey.Vehicle := Your_Car;


Spec-Zone.ru

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