2

我正在尝试用受保护的对象包装散列映射,以便可以通过多个任务访问它。我希望受保护类型的过程可用,但将哈希映射和元素记录定义移动到包私有部分会很好。

这里的示例代码:

package Thing_Protected is

   type Thing_Info is record
      Key : Ada.Strings.Unbounded.Unbounded_String;
      Counter_Value : Natural := 0;
   end record;

   package Thing_Info_Maps is new Ada.Containers.Hashed_Maps
      (Key_Type => Ada.Strings.Unbounded.Unbounded_String,
      Element_Type => Thing_Info,
      Hash => Ada.Strings.Unbounded.Hash,
      Equivalent_Keys => Ada.Strings.Unbounded."=");

   protected type Thing is
      procedure Increment (Key : String);
      procedure Another_Thing (Key : String);
   private
      Thing_Map : Thing_Info_Maps.Map;
   end Thing;

private

   -- move Thing_Info, Thing_info_maps into here.

end Thing_Protected;

我尝试将 Thing_Info 定义为私有类型。但我不确定如何将 Thing_Info_Maps 包定义为私有但仍从受保护的对象类型访问它。

所以我真的找不到试图找到一种方法来获得这样的东西:

package Thing_Protected is

   type Thing_Info is private;
   package Thing_Info_Maps is private;

   protected type Thing is
      procedure Increment (Key : String);
      procedure Another_Thing (Key : String);
   private
      Thing_Map : Thing_Info_Maps.Map;  --  <<- how would we know about .Map??
   end Thing;

private

   type Thing_Info is record
      Key : Ada.Strings.Unbounded.Unbounded_String;
      Counter_Value : Natural := 0;
   end record;

   package Thing_Info_Maps is new Ada.Containers.Hashed_Maps
      (Key_Type => Ada.Strings.Unbounded.Unbounded_String,
      Element_Type => Thing_Info,
      Hash => Ada.Strings.Unbounded.Hash,
      Equivalent_Keys => Ada.Strings.Unbounded."=");

end Thing_Protected;
4

3 回答 3

7

使用 Ada 2005,您可以使用受保护的接口:

package Thing_Protected is

   type Thing is protected interface;

   procedure Increment     (Object : in out Thing; Key : String) is abstract;
   procedure Another_Thing (Object : in out Thing; Key : String) is abstract;

   -- As the implementation type is private, we need a
   -- factory method which returns an instance of the
   -- implementation type:
   function Create return Thing'Class;

private

   type Thing_Info is record
      Key : Ada.Strings.Unbounded.Unbounded_String;
      Counter_Value : Natural := 0;
   end record;

   package Thing_Info_Maps is new Ada.Containers.Hashed_Maps
      (Key_Type => Ada.Strings.Unbounded.Unbounded_String,
      Element_Type => Thing_Info,
      Hash => Ada.Strings.Unbounded.Hash,
      Equivalent_Keys => Ada.Strings.Unbounded."=");

   protected type Thing_Impl is new Thing with
      overriding procedure Increment (Key : String);
      overriding procedure Another_Thing (Key : String);
   private
      Thing_Map : Thing_Info_Maps.Map;
   end Thing_Impl;

end Thing_Protected;
于 2013-10-11T08:20:28.810 回答
2

how would we know about .Map??

这样的事情怎么样?

Generic
    type Thing_Info is private;
    with package Thing_Info_Maps is new Ada.Containers.Hashed_Maps(
            Key_Type        => Ada.Strings.Unbounded.Unbounded_String,
            Element_Type    => Thing_Info,
            Hash            => Ada.Strings.Unbounded.Hash,
            Equivalent_Keys => Ada.Strings.Unbounded."=");
Package INFO is

    protected type Thing is
        procedure Increment     (Key : String);
        procedure Another_Thing (Key : String);
    private
        -- BEHOLD THE POWER OF GENERICS!!
        Thing_Map : Thing_Info_Maps.Map;
    end Thing;

Private
    -- PRIVATE STUFF
End INFO;
于 2013-10-11T04:33:20.777 回答
2

这个包的用户需要知道里面有一个受保护的类型吗?如果没有,您可以在规范的可见部分声明一个(标记的)类型,并使用原始子程序进行匹配:

package Thing_Protected is

   type Thing is tagged limited private;
   procedure Increment (This : in out Thing; Key : String);
   procedure Another_Thing (This : in out Thing; Key : String);

private

   type Thing_Info is record
      Key : Ada.Strings.Unbounded.Unbounded_String;
      Counter_Value : Natural := 0;
   end record;

   package Thing_Info_Maps is new Ada.Containers.Hashed_Maps
     (Key_Type => Ada.Strings.Unbounded.Unbounded_String,
      Element_Type => Thing_Info,
      Hash => Ada.Strings.Unbounded.Hash,
      Equivalent_Keys => Ada.Strings.Unbounded."=");

   protected type Thing_Imp is
      procedure Increment (Key : String);
      procedure Another_Thing (Key : String);
   private
      Thing_Map : Thing_Info_Maps.Map;
   end Thing_Imp;

   type Thing is tagged limited record
      Imp : Thing_Imp;
   end record;

end Thing_Protected;

身体像

package body Thing_Protected is

   procedure Increment (This : in out Thing; Key : String) is
   begin
      This.Imp.Increment (Key);
   end Increment;

   procedure Another_Thing (This : in out Thing; Key : String) is
   begin
      This.Imp.Another_Thing (Key);
   end Another_Thing;

   protected body Thing_Imp is
      procedure Increment (Key : String) is
         N : constant Ada.Containers.Count_Type := Thing_Map.Length;
      begin
         null;
      end Increment;
      procedure Another_Thing (Key : String) is
      begin
         null;
      end Another_Thing;
   end Thing_Imp;

end Thing_Protected;
于 2013-10-11T08:27:43.717 回答