Взаимно рекурсивные типы
Бывают случаи, когда необходимо иметь два (или более) типа, которые являются взаимно рекурсивными.
Такие типы содержат указатели, ссылаются друг на друга.
В качестве примера рассмотрим типы: Doctor - врач и Patient - пациент.
Эти типы нуждаются в указателях, которые ссылаются друг на друга.
Ада потребует поместить оба этих типа в один пакет.
Чтобы сохранить возможность раздельной компиляции, можно описать два базовых типа в одном пакете:
package Doctors_And_Patients is
type Doctor is abstract tagged null record; type Doctor_Ptr is access all Doctor'Class; type Patient is abstract tagged null record; type Patient_Ptr is access all Patient'Class; end Doctors_And_Patients; |
Позже, для непосредственного фактического использования, можно создать в самостоятельных пакетах производные типы, которые используют описания этих базовых типов.
Подобные описания могут иметь следующий вид:
with Doctors_And_Patients; use Doctors_And_Patients;
package Doctors is type Doc is new Doctor with private; -- подпрограммы . . . private type Doc is new Doctor with record Pat : Patient_Ptr; . . . end record; end Doctors; with Doctors_And_Patients; use Doctors_And_Patients; package Patients is -- далее подобно Doctors... . . . |
При описании базовых типов, в пакете Doctors_And_Patients, можно также описать операции, которые будут определять элементарную функциональность базовых типов.
Дополнительные операции могут быть добавлены позднее, в описаниях производных типов (например в типе Doc).
Примечательно, что тело одного пакета может видеть спецификацию другого пакета.
Таким образом, тела пакетов могут иметь следующий вид:
with Doctors; use Doctors; package body Patients is
-- тело пакета Patients имеет доступ к сервисам Doctors -- описанным в спецификации пакета Doctors . . . end Patients; with Patients; use Patients; package body Doctors is -- тело пакета Doctors имеет доступ к сервисам Patients -- описанным в спецификации пакета Patients . . . end Doctors; |