2013-10-11 3 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와 관련이 있다는 것이 명백하지는 않다고 생각한다. 특히 'ada'라는 태그가 붙은 상위 15 개 투표 결과가 있었기 때문에 제목에 Ada가 하나도 없었습니다. –

+0

나는 그것을 돌볼 것이다. –

답변

7

, 당신은 보호 된 인터페이스를 사용할 수 있습니까? 그렇지 않으면, 당신은 원시 서브 프로그램과 사양의 보이는 부분에 (태그) 형이 일치하는 선언 할 수 :

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

이것은 훌륭한 답변이지만 Create 기능을 구현하는 방법을 잘 모르겠습니다.나는 Thing'Class에 대한 액세스를 반환하여 작동하도록했습니다. Thing'Class를 반환하려고하면 "제한된 개체의 초기화가 집계 또는 함수 호출이 필요합니다"또는 "예상되는 형식"Thing_Impl "이 (가) 정의 된 ...과 같은 흥미로운 오류가 발생했습니다. 복합 유형이 발견되었습니다."동기화 된 인터페이스는 제한된 유형 그래서 복사 할 수 없습니까? –

+0

아, 생각났습니다. 확장 return 문을 사용해야합니다. http://www.adacore.com/adaanswers/gems/ada-gem-10/ –

+0

보호 된 유형은 본질적으로 제한되어 있으므로 보호 된 인터페이스입니다. 연장 계산서 없이는 제대로 작동 할 수 있지만, 시도한 내용을 알지 못해서 내가 잘못한 것을 말할 수는 없습니다. – flyx

2

how would we know about .Map??

어떻게 이런 일에 대해? 이 패키지의 사용자가 거기에 보호 종류가 있다는 것을 알고해야합니까

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

패키지 인터페이스에 hashed_map을 추가하지 않습니까? 나는 Increment()와 Another_Thing()을 공개적으로 사용할 수있게하고 싶었지만 사용자는 배후에서 hashmap을 사용하고 있다는 것을 알 필요가 없다. –

+0

입니다; 나는 당신이 개인적인 타입으로'Thing' 자체를 만들 수 있고, 몸체의 이름 바꾸기/줄 바꿈과 함께 스펙 안에'Procedure Increment (Item : in Thing; Key : String)'을 가지고 있거나 개인 타입'Thing_Map'을 가지고 있다고 가정합니다. 'Thing_Info_Maps'의 하위 유형 이름 바꾸기 ... – Shark8

2

: 에이다 2005

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; 
관련 문제