Ада-95. Компилятор GNAT
66ac8edd

Лимитированные приватные типы (limited private types)


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

В качестве демонстрации сказанного, рассмотрим следующий пример:

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 описан как лимитированный приватный тип.

Также, в спецификации пакета, описана функция знака операции сравнения на равенство "=".

Реализация алгоритма этой функции должна быть помещена в тело пакета.




Примечательно, что при совмещении знака операции равенства "=" автоматически производится неявное совмещение знака операции неравенства "/=".

При этом следует учесть, что если функция реализующая действие знака операции равенства "="

возвращает значение тип которого отличается от предопределенного логического типа Boolean

(полное имя - Standard.Boolean), то совмещение знака операции неравенства "/="

необходимо описать явно.

Следует заметить, что Ада разрешает переопределять знак операции равенства для всех типов.

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

Например, для показанного выше типа Our_Text, спецификация такой процедуры может иметь следующий вид:

. . . procedure Init (T : in out Our_Text; S : in String); . . .

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


Содержание раздела