Хотя приватные типы позволяют разработчику получить значительный контроль над действиями пользователя, ограничив способности пользователя в манипулировании объектами, бывают случаи когда необходимо запретить пользователю приватного типа использовать даже такие предопределенные операции как сравнение и присваивание.
В качестве демонстрации сказанного, рассмотрим следующий пример:
| package Compare_Demo is
type Our_Text is private; . . . private type Our_Text (Maximum_Length : Positive := 20) is record Length : Index := 0; Value : String(1..Maximum_Length); end record; . . . end Compare_Demo; |
Здесь, тип Our_Text описан как приватный и представляет из себя запись.
В данной записи, поле длины Length определяет число символов которое содержит поле Value (другими словами - число символов которые имеют смысл).
Любые символы, находящиеся в позиции от Length + 1 до Maximum_Length будут нами игнорироваться при использовании этой записи.
Однако, если мы попросим компьютер сравнить две записи этого типа, то он, в отличие от нас, не знает предназначения поля Length.
В результате, он будет последовательно сравнивать значения поля Length
и значения всех остальных полей записи.
Очевидно, что алгоритм предопределенной операции сравнения в данной ситуации не приемлем, и нам необходимо написать собственную функцию сравнения.
Для подобных случаев Ада предусматривает лимитированные приватные типы.
Изменим рассмотренный выше пример следующим образом:
| package Compare_Demo is
type Our_Text is limited private; . . . function "=" (Left, Right : in Our_Text) return Boolean; . . . private type Our_Text (Maximum_Length : Positive := 20) is record Length : Index := 0; Value : String(1..Maximum_Length); end record; . . . end Compare_Demo; |
Теперь, тип Our_Text описан как лимитированный приватный тип.
Также, в спецификации пакета, описана функция знака операции сравнения на равенство "=".
Реализация алгоритма этой функции должна быть помещена в тело пакета.
|
. . . procedure Init (T : in out Our_Text; S : in String); . . . |