2013-10-11 1 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

Думаю, теперь не так очевидно, что это связано с адой. Тем более, что из 15 лучших опрошенных вопросов отметили «ada», только у одного не было Ada в названии. –

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

Это отличный ответ, но я не совсем уверен, как реализовать функцию Create.Мне удалось заставить его работать, возвращая доступ к Thing'Class. Попытка вернуть Thing'Class дает мне интересные ошибки, такие как «инициализация ограниченного объекта требует агрегатного или функционального вызова» или «ожидаемого типа Thing_Impl», определенного в ..., найденного составного типа «Было бы это потому, что синхронизированные интерфейсы являются ограниченными типами так что нельзя копировать? –

+0

А, я думаю, я понял это. Мне нужно использовать расширенный оператор return: http://www.adacore.com/adaanswers/gems/ada-gem-10/ –

+0

Защищенный тип по своей сути ограничен, так что это защищенные интерфейсы. Вы можете определенно заставить его работать без расширенного оператора return, но, поскольку я не знаю, что вы пробовали, я не могу сказать вам, что вы сделали неправильно. – 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' сам по себе частным типом и иметь« процедуру Increment (Item: in the 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; 
Смежные вопросы