是否可以从另外两个通用包访问通用包的实例?

时间:2013-07-28 13:12:43

标签: generics ada

我正在写一个通用库。我有一个受保护的对象需要由两个包中的代码访问。包含对象的包和需要访问它的包都是通用的。为清楚起见,我会将包Main_PkgSecond_PkgObject_Pkg称为。所有三个包都使用相同的类型进行实例化。

对于非通用代码,我只需在Object_PkgMain_Pkg中使用Second_Pkg。我知道我不能用通用包来做这件事,因为Object_Pkg不会被实例化。

到目前为止,我已尝试Main_Pkg创建Object_Pkg

的实例
package Instance_Of_Object_Pkg is new Object_Pkg(Custom_Type)

Second_Pkg使用

等代码访问它
Main_Pkg.Instance_Of_Object_Pkg.Object.Procedure

但是我收到编译错误

invalid prefix in selected component "Main_Pkg"

这是我第一次使用泛型类型,因此我不确定导致问题的原因或接下来要尝试的内容。是否可以这样做,如果是这样的话?

2 个答案:

答案 0 :(得分:4)

我认为您可以使用generic formal package

不打扰受保护的对象(能够访问任何应该证明这一点)

generic
   type T is private;
package Object_Pkg is
   Arr : array (1 .. 10) of T;
end Object_Pkg;

然后指定要使用类型Main_Pkg实例化T并使用相同类型的Object_Pkg实例化,如下所示:

with Object_Pkg;
generic
   type T is private;
   with package Inst is new Object_Pkg (T);
package Main_Pkg is
   Obj : T := Inst.Arr (1);
end Main_Pkg;

现在,首先实例化Object_Pkg

with Object_Pkg;
package Object_Inst is new Object_Pkg (T => Integer);

然后使用相同类型和Main_Pkg的新实例实例化Object_Pkg

with Object_Inst;
with Main_Pkg;
package Main_Inst is new Main_Pkg (T => Integer,
                                   Inst => Object_Inst);

答案 1 :(得分:0)

如果Main_Pkg和Second_Pkg足够紧密相关,你将会有其中一个包访问另一个包中定义的东西,那么将它们作为完全独立的通用包可能不是组织它们的正确方法。考虑让他们成为其他包装的孩子。

听起来你有像

这样的东西
generic
    type T is private;
package Main_Pkg is ... end Main_Pkg;

generic
    type T is private;
package Second_Pkg is ... end Second_Pkg;

请注意,这并未设置Main_Pkg和Second_Pkg必须使用T的相同类型进行实例化的规则。如果您的程序显示类似

的内容
package Main_Inst is new Main_Pkg (T => T1);
package Second_Inst is new Second_Pkg (T => T2);  -- some different type

然后显然Second_Inst和Main_Inst无法真正相互通信(使用泛型类型T)。使用相同类型对它们进行实例化并不会奇怪地导致之前没有连接的两个实例之间的连接。

因此两个泛型之间必须有一些联系。通用正式包是一种可能性,就像Simon提出的那样。另一种可能性是Second_Pkg有一个通用的正式包参数,它是Main_Pkg的实例:

generic
    with package With_Main_Pkg is new Main_Pkg (<>);
package Second_Pkg is ...

现在Second_Pkg可以引用With_Main_Pkg(它可以使用With_Main_Pkg.T来获取Main_Pkg的正式类型。)

但是将Main_Pkg和Second_Pkg放在一些较大的包中可能是最简单的,并且将T作为该较大包的参数而不是Main_Pkg和Second_Pkg。

generic
    type T is private;
package Larger_Pkg is

    package Object_Inst is new Object_Pkg (T);
        -- this might belong in Larger_Pkg's body, instead of the specification.
        -- The bodies of Main_Pkg and Second_Pkg would both have it available.

    package Main_Pkg is ...
    package Second_Pkg is ...

end Larger_Pkg;

如果除了T之外还需要一些其他通用参数,那么Main_Pkg和Second_Pkg也可能是通用的。我不知道。此解决方案不允许您将Main_Pkg和Second_Pkg的规范放在单独的单元中;你必须将它们嵌套在Larger_Pkg中。但是你仍然可以通过使用单独的编译(package body Main_Pkg is separate;)来分离主体。如果Main_Pkg和Second_Pkg可以是泛型,则可以将它们设为子单位:

generic
package Larger_Pkg.Main_Pkg is ...
end Larger_Pkg.Main_Pkg;

但是然后Object_Inst不能在Larger_Pkg的主体中。不过,它可能属于私人部分。

无论如何,最好的答案部分取决于这些包在您的真实程序中应该代表什么概念。