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

       

Принудительная инициализация


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

Чтобы добиться подобного эффекта в Аде, необходимо при описании объекта указать присваивание начального значения, которое осуществляется в результате вызова функции.

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

Рассмотрим следующий пример:

package Stacks is

type Stack is tagged private;

function Init return Stack;

-- другие операции . . .

private type List is array(1..10) of Integer; type Stack is record

Values : List; Top : Integer range 0..10; 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(1..10) of Integer;

-- ...даже если вы не стремитесь иметь здесь дискриминант type Stack is record

Values : List; Top : Integer range 0..10; end record; end Stacks;

with Stacks; use Stacks; procedure Main is

A : Stack := Init; B : Stack; -- теперь это недопустимо! -- вы должны вызвать функцию для инициализации B

begin null; end Main;

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



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