从Ada的受保护对象访问私有类型

时间:2013-10-11 00:48:58

标签: multithreading ada

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

此处的示例代码:

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;

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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;

答案 2 :(得分: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;