Как завершить Ada защищенный тип - PullRequest
2 голосов
/ 04 марта 2011

Учитывая защищенный тип Ada:

protected type A is
    procedure Foo;
    ...
private
    M : Map;
    ...
end A;

Как бы вы внедрили или эмулировали Завершить процедуру, которая вызывается, когда защищенный объект завершен?

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

1 Ответ

5 голосов
/ 04 марта 2011

Оберните закрытые члены, которые участвуют в финализации, в одну или несколько записей, полученных из Ada.Finalization.Controlled или Limited_Controlled.Когда защищенный объект будет завершен, эти закрытые члены также будут соответственно завершены.

Вот быстрый, рабочий (!) Пример:

with Text_IO; use Text_IO;
with Ada.Finalization;
with Ada.Containers.Ordered_Maps;
with Ada.Unchecked_Deallocation;

procedure Protected_Final is

   Instance_Counter : Natural := 1;

   package Int_Map is new Ada.Containers.Ordered_Maps (Integer, Integer);
   subtype Map is Int_Map.Map;

   type Map_Wrapper is new Ada.Finalization.Controlled with record
      ID : Natural;
      M  : Map;
   end record;

   overriding procedure Initialize(Item : in out Map_Wrapper);

   overriding procedure Finalize(Item : in out Map_Wrapper);

   procedure Initialize(Item : in out Map_Wrapper) is
   begin
      Item.ID := Instance_Counter;
      Instance_Counter := Instance_Counter + 1;
      Put_Line("Initialize the Map part as instance" & Natural'Image(Item.ID));
   end Initialize;

   procedure Finalize(Item : in out Map_Wrapper) is
   begin
      Put_Line("Clean up the Map stuff for instance" & Natural'Image(Item.ID));
   end Finalize;

   protected type A is
      procedure Foo;
   private
      M : Map_Wrapper;
   end A;

   protected body A is

      procedure Foo is 
      begin
         null;
      end Foo;
   end A;

   Test_Item : A;

   type A_Handle is access A;

   procedure Free is new Ada.Unchecked_Deallocation(A, A_Handle);

   Test_Item_Handle : A_Handle;

begin
   Test_Item_Handle := new A;

   Free(Test_Item_Handle);
end Protected_Final;

Запустив это, я получаю:

C:\sandbox\protected_final
Initialize the Map part as instance 1
Initialize the Map part as instance 2
Clean up the Map stuff for instance 2
Clean up the Map stuff for instance 1
[2011-03-04 08:37:29] process terminated successfully (elapsed time: 00.21s)

«Внешние» сообщения «Инициализация / Очистка» являются результатом статически объявленного экземпляра Test_Item, в то время как внутренняя пара происходит из динамически назначенного и освобожденного Test_Item_Handle.

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