Принудительная инициализация
Принудительная инициализация
В объектно-ориентированных языках программирования, которые используют классы (например язык C++), можно принудительно навязать автоматическую инициализацию для всех объектов класса, снабдив класс конструктором, который гарантированно вызывается при создании объекта.Чтобы добиться подобного эффекта в Аде, необходимо при описании объекта указать присваивание начального значения, которое осуществляется в результате вызова функции.Следует заметить, что в данном случае мы не рассматриваем средства, которые предоставляют контролируемые типы Ады.Рассмотрим следующий пример:
package Stacks is type Stack is tagged private; function Init return Stack; -- другие операции
. . .private
type List is array(0) of Integer;
type Stack is record Values : List; Top : Integer range 0; end record; end Stacks;with Stacks; use Stacks; procedure Main is A : Stack := Init; B : Stack;begin null; end Main; |
В этом примере объект A будет надежно инициализирован для представления пустого стека.Причем, для этого можно использовать только функции предусмотренные пакетом Stacks.Выполнить инициализацию такого объекта каким-либо другим способом - нельзя, поскольку его тип - приватный.Однако, не трудно заметить, что объект B - не инициализирован.Таким образом видно, что Ада не предъявляет никаких требований по принудительной инициализации объектов.
Чтобы в подобных случаях возложить контроль за инициализацией объектов на компилятор необходимо использовать дискриминанты.Существует возможность указать наличие дискриминанта в неполном описании типа при фактическом отсутствии дискриминанта в полном описании типа.Поскольку Ада предпочитает ограниченные (constrained) объекты (то есть те объекты, размер которых известен), то применение комбинации из дискриминанта и приватного типа послужит причиной того, что компилятор будет требовать от программиста явной инициализации всех объектов такого типа.
package Stacks is type Stack(<>) is private; -- указание того, что Stack может иметь дискриминант... function Init return Stack; -- другие операции . . .private type List is array(0) of Integer; -- ...даже если вы не стремитесь иметь здесь дискриминант type Stack is record Values : List; Top : Integer range 0; end record; end Stacks;with Stacks; use Stacks; procedure Main is A : Stack := Init; B : Stack; -- теперь это недопустимо! -- вы должны вызвать функцию для инициализации Bbegin null; end Main; |
Подобный подход может показаться несколько интуитивным, однако за счет явности описаний инициализации он повышает общую читабельность исходного текста.