如何最终确定Ada保护类型

时间:2011-03-04 13:41:47

标签: types ada protected

给定Ada保护类型:

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

如何实现或模拟在何时调用的 Finalize 过程 受保护的对象是否已完成?

基本上我需要使用受保护类型的私有成员进行一些管理(迭代某些地图等)。

1 个答案:

答案 0 :(得分:5)

将包含在最终版中的一部分的私有成员包含在从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)

“外部”Initialize / Cleanup消息是静态声明的Test_Item实例的结果,而内部对来自动态分配和释放的Test_Item_Handle。