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

このパッケージのユーザーは、そこに保護された型があることを知る必要がありますか? そうでない場合は、一致するプリミティブサブプログラムを使用して、仕様の可視部分で (タグ付きの) 型を宣言できます。

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 に答える
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 に答える