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

       

Счетчик использования


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

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

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

Объектов-пользователей базы данных может быть множество.

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

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

Далее, при последующем создании объектов этого типа, открытие новых файлов для протоколирования состояний не выполняется.

При удалении не используемых объектов, файл протокола должен быть закрыт только тогда, когда удалены все объекты указанного типа данных.

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

Для решения таких задач удобно использовать контролируемые типы.

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

with Ada.Text_IO; with Ada.Finalization; use Ada.Finalization;



package Log is

type Item is private;

procedure Put_To_Log (Self: in out Item; S: in String);

private

type Item is new Limited_Controlled with

record

. . . -- описание полей расширения

end record;

procedure Initialize (Self: in out Item); procedure Finalize (Self: in out Item);

The_Log_File: Ada.Text_IO.File_Type; The_Counter: Natural := 0;

end Log;

Здесь тип Item описывает тип объектов при обработке которых используется общий файл протокола The_Log_File.

Для вывода информации о состоянии объекта типа Item в файл протокола The_Log_File

используется процедура Put_To_Log.

Для подсчета количества существующих в текущий момент объектов типа Item




используется переменная The_Counter.

Тело данного пакета может быть описано следующим образом:

package body Log is

procedure Initialize (Self: in out Item) is

begin

The_Counter := The_Counter + 1;

if The_Counter = 1 then

Ada.Text_IO.Open (File => The_Log_File, Mode => Ada.Text_IO.Append_File, Name => "log.txt"); end if; end Initialize;

procedure Finalize (Self: in out Item) is

begin

if The_Counter = 1 then

Ada.Text_IO.Close (The_Log_File); end if;

The_Counter := The_Counter - 1; end Finalize;

procedure Put_To_Log (Self: in out Item; S: in String) is

begin

. . . -- вывод необходимых данных в файл The_Log_File

end Put_To_Log;

end Log;

Как видно из примера, открытие файла протокола The_Log_File, при создании первого объекта типа Item, и инкремент количества существующих в текущий момент объектов типа Item

в переменной The_Counter

выполняется автоматически вызываемой процедурой Initialize.

Декремент количества существующих в текущий момент объектов типа Item

в переменной The_Counter и закрытие файла протокола The_Log_File

выполняется автоматически вызываемой процедурой Finalize.

Следует заметить, что при рассмотрении данного примера мы не заостряли внимание на структуре типа Item и реализации процедуры Put_To_Log, которая выводит информацию о состоянии объекта в файл протокола, поскольку в данном случае это не имеет принципиального значения.


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