开发者

How to finalize an Ada protected type

开发者 https://www.devze.com 2023-02-14 16:20 出处:网络
Given an Ada protected type: protected type A is procedure Foo; ... private M : Map; ... end A; How would you开发者_Python百科 implement or emulate a Finalize procedure that is called when

Given an Ada protected type:

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

How would you开发者_Python百科 implement or emulate a Finalize procedure that is called when the protected object is finalized?

Basically I need to do some house keeping using the private members of the protected type (iterating over some map and so on).


Wrap the private members that have a part in the finalization in one or more records derived from Ada.Finalization.Controlled or Limited_Controlled. When the protected object is finalized, those private members will be correspondingly finalized as well.

Here's a quick, working(!) example:

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;

Running this I get:

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)

The "outer" Initialize/Cleanup messages come are a result of the statically declared Test_Item instance, while the inner pair are from the dynamically allocated and deallocated Test_Item_Handle.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号