2017-03-12 91 views
3

我有一個通用的包裝Containers.Stacks看起來大致是阿達通用包擴展

generic 
    type Value_Type is private; 
package Containers.Stacks with Preelaborate is 

    --Node stuff 

    type Stack is new Container with private; 

    --Other Stack stuff 
    --Private stuff 
end Containers.Stacks; 

一切有關的(似乎)工作得很好。我想重用這個實現來創建一個擴展但更窄的目的棧。我想出了以下內容:

​​

問題的關鍵是,我不希望有重新實現所有公共堆棧的東西,只爲特定整數堆棧。這是有效的,但留下了一個醜陋而奇怪的Containers.Integer_Stacks.StackContainers.Integer_Stacks.Stacks.Stack,我想避免它。然而,試圖將包初始化放在私有部分中,也隱藏了所有的子例程。有沒有辦法做到我想做的事,或者說用戶必須要處理的兄弟包初始化存在一個更合適的方法?

替代做法: 我發現這是可能的定義的Containers.Stacks子包稱爲Containers.Stacks.Integer像這樣:

generic 
    with function "+"(Left, Right: Value_type) return Value_Type is <>; 
package Containers.Stacks.Integer is 
    procedure Add(Self : in out Stack); 
end Containers.Stacks.Integer; 

而這個工作。除了現在我不能撥打Stack.Add,我不得不打電話給Add(Stack)

回答

0

其他擬議的答案都因各種原因已經很大了,但我認爲它太重要了,自動暴露在同級的基礎容器類型的子程序。因此,最好的答案是我最初的實施。希望其他開發人員會發現其他答案有幫助。

4

你可以看看

with Containers.Stacks; 
generic 
    type Value_Type is range <>; 
    with package Basis_Stack is new Containers.Stacks (Value_Type => Value_Type); 
package Containers.Integer_Stacks with Preelaborate is 
    type Stack is new Basis_Stack.Stack with private; 
... 

這並不需要用戶適當實例Containers.Stacks自己。

2

你對解決方案的想法並不是給你一個更窄的類型,而是一個更多操作。

如果你想要一個更窄的類型,你在哪裏發生在內部使用現有的類型,你可以做這樣的(未經測試源)的Containers.Integer_Stack

private with Containers_Stack; 

generic 
    type Value_Type is range <>; 
package Containers.Integer_Stack 
    with Preelaborate 
is 
    type Instance is tagged private with null record; 

    procedure Add (Item : in out Instance); 
    procedure Subtract (Item : in out Instance); 
private 
    package Internal_Stack is new Containers.Stacks (Value_Type); 

    type Instance is tagged private with 
     record; 
     Data : Internal_Stack.Stack; 
     end record; 
end Containers.Integer_Stack; 

這樣,客戶端只能使用完全相同的您在包裝規格中列出的操作明確

+0

「試圖將包初始化private部分,但是,也隱藏了所有的子程序。」 –

+0

是的。這就是完成這一點的原因,正如你寫的那樣,你想創建一個「狹義目標堆棧」。您仍然可以從「Containers.Stacks.Stack」中爲您的「窄目標棧」製作公開版本的操作。 –