0

私は汎用ライブラリを書いています。2 つのパッケージのコードでアクセスする必要がある保護されたオブジェクトがあります。オブジェクトを含むパッケージとそれにアクセスする必要があるパッケージの両方が汎用です。わかりやすくするために、パッケージMain_PkgSecond_Pkgと呼びます。Object_Pkg3 つのパッケージはすべて同じタイプでインスタンス化されます。

非汎用コードでは、単純に 'with' Object_PkginMain_PkgSecond_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"

ジェネリック型を扱うのはこれが初めてなので、何が問題を引き起こしているのか、次に何を試せばよいのかわかりません。これを行うことはまったく可能ですか?

4

2 に答える 2

4

一般的な正式なパッケージを使用できる可能性があると思います。

保護されたオブジェクトを気にしない(にでもアクセスできることはポイントを示すはずです)

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

次に、次のように、 が型でインスタンス化され、同じ型でMain_Pkgがインスタンス化されるように指定します。TObject_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);
于 2013-07-28T14:58:12.417 に答える
0

Main_Pkg と Second_Pkg が十分に密接に関連しているため、これらのパッケージの 1 つが他のパッケージで定義されているものにアクセスする場合、それらを完全に別個の汎用パッケージにすることは、それらを整理する正しい方法ではありません。両方を他のパッケージの子にすることを検討してください。

あなたは次のようなものを持っているように聞こえます

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 を使用して) 互いに通信できませんでした。それらを同じ型でインスタンス化しても、以前は接続が存在しなかった 2 つのインスタンス化の間に魔法のように接続が発生することはありません。

したがって、2 つのジェネリックの間に何らかの関連性がなければなりません。一般的なフォーマル パッケージは、Simon が提示した 1 つの可能性です。もう 1 つの可能性は、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.TMain_Pkg の正式な型を取得するために使用できます)。

ただし、Main_Pkg と Second_Pkg をより大きなパッケージに入れ、Main_Pkg と Second_Pkg の代わりに T をそのより大きなパッケージのパラメーターにするのが最も簡単かもしれません。

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 の本体に含めることはできません。ただし、それは私的な部分にある可能性があります。

とにかく、最良の答えは、これらのパッケージが実際のプログラムでどのような概念を表すことになっているかによって部分的に異なります。

于 2013-07-29T15:59:14.230 に答える