2017-03-12 94 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”中为您的“窄目标栈”制作公开版本的操作。 –