2013-10-11 78 views
2

我試圖用受保護的對象包裝散列映射,以便可以通過多個任務來訪問它。我希望受保護類型的過程可用,但將散列映射和元素記錄定義移動到軟件包專用部分會很好。從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; 
+0

我編輯了自己的冠軍。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

+0

我想現在它不像ada相關那麼明顯。尤其是在排名前15的投票標題爲「ada」的問題中,只有一個在標題中沒有Ada。 –

+0

我會照顧的。 –

回答

7

隨着2005年的Ada,你可以使用一個保護的接口:

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; 
+0

這是一個很好的答案,但我不完全確定如何實現Create函數。我設法通過返回一個Thing'Class來訪問它。試圖返回一個Thing'Class給我有趣的錯誤,如「初始化有限對象需要聚集或函數調用」或「期望類型」Thing_Impl「定義在......,找到一個複合類型」這是因爲同步接口是有限類型所以不能複製? –

+0

啊,我想我明白了。我需要使用擴展返回語句:http://www.adacore.com/adaanswers/gems/ada-gem-10/ –

+0

受保護的類型固有地受到限制,受保護的接口也是如此。你一定可以在沒有延期退貨聲明的情況下工作,但由於我不知道你所嘗試的是什麼,我不能告訴你你做錯了什麼。 – flyx

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; 
+0

這是不是仍然把hashed_map放在包界面中?我想我想公開提供Increment()和Another_Thing(),但用戶不需要知道我在幕後使用HashMap。 –

+0

它是;我想你可以把'Thing'本身變成一個私有類型,並且在規範中有'procedure Increment(Item:in Thing; Key:String)',在主體中重命名/包裝或者有一個私有類型'Thing_Map',它是'Thing_Info_Maps'的子類型重命名... – Shark8

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;