Используйте универсальный пакет - PullRequest
2 голосов
/ 04 мая 2011

мой вопрос очень прост. У меня 2 универсальных пакета. Я использую каждый пакет 2 раза (один раз для целых чисел и строки за один раз). У меня есть «основной» файл, который использует пакет, выбранный пользователем. - package1 с целым числом - или package1 со строкой - или package2 с целым числом - или package2 со строкой

procedure main is
     package aB is new package1(integer, false, afficheInteger, true);
    --package aB is new package1(Unbounded_String, true, afficheUnbounded, true);
    --package aB is new package2(1,integer, false, afficheInteger, true);
    --package aB is new package2(1, Unbounded_String, true, afficheUnbounded, true);

начать aB.init (); .....

Цель состоит в том, чтобы использовать один и тот же код (основной) для 4 пакетов.

К сожалению, я не могу найти, как это сделать правильно. На данный момент я помещаю список пакетов и комментирую пакеты, которые я не использую. Можно ли сделать псевдо, если в начале или init пакет в начале? Может быть, с параметром пакета в основной функции?

Большое спасибо и извините за мой английский!

Обновление:

Можно ли передать параметр пакета в функцию? Как это:

procedure init_paquetage1_int is
    package aB is new packA(integer, false, afficheInteger, true);
begin
    main(aB);
end init_paquetage1_int; 

procedure main(aB : packA) is
begin
    aB.init();
    ....
end main;

Это не работает.

Ответы [ 2 ]

6 голосов
/ 04 мая 2011

OK.Во-первых, я не вижу возможности, чтобы вы могли надеяться, что это сработает, если только процедуры, которые вы вызываете в пакете (-ах), не имеют одинакового профиля параметров, независимо от того, какой тип был использован.Как правило, универсальный пакет будет иметь по крайней мере одну подпрограмму, которая использует один из типов, с которыми вы создали его экземпляр в параметрах подпрограммы (или в качестве возвращаемого типа).

Если подпрограммы, которые вы хотите использовать, на самом деле имеют идентичныепрофили, я могу вспомнить пару вещей, которые вы могли бы сделать.Во-первых, используйте указатель на подпрограмму , которую вы хотите вызвать, и передайте ее.

   type Init_Routine is access procedure ();
begin
   main (ab.Init'access);

Во-вторых, все ваши универсальные пакеты будут содержать теговые типы, полученные изобщий родительский тип тега abstract, в котором подпрограммы, которые вы хотите вызвать, определены как подпрограммы abstract в родительском элементе.Если вы сделаете это, вы можете использовать динамическую диспетчеризацию для выбора между ними во время выполнения.

package Parent is
   type Instance is abstract tagged null record;
   type Dispatching_Instance_Ptr is access all Instance;
   procedure Init (I : in out Instance) is abstract;
end Parent;

generic 
   --// Whatever your generic parameters are...
Package1 is
    type Instance is new Parent.Instance with null record;
    procedure Init (I : in out Instance);
    ...
end Package1;
--// (Package2 looks similar)

Переход к вызывающему коду:

    Choice : Parent.Dispatching_Instance_Ptr;
begin
    --// Let's assume the user "chooses" package aB
    Choice := new'aB.Instance;
    main (Choice);

... и для main:

procedure main(xx : in Parent.Dispatching_Instance_Ptr) is
begin
   Parent.Init(xx.all);  --// This should dynamic dispatch to the proper init routine
   ....
end main;

Примечание: я не запускал это через компилятор, поэтому, возможно, есть небольшие проблемы.Я уже нашел и исправил пару.

2 голосов
/ 04 мая 2011

Каждый раз, когда вы создаете экземпляр общего пакета, он рассматривается как отдельный пакет. Поэтому вам нужно использовать разные имена пакетов для каждого экземпляра.

procedure main is
     package aA is new package1(integer, false, afficheInteger, true);
     package aB is new package1(Unbounded_String, true, afficheUnbounded, true);
     package aC is new package2(1,integer, false, afficheInteger, true);
     package aD is new package2(1, Unbounded_String, true, afficheUnbounded, true);
...

Теперь вы можете использовать каждый из них как отдельный пакет.

aA.init();
aB.init();
...

Вы можете передавать процедуры как параметры, но не как пакеты.

Если вы все еще не понимаете дженерики, я предлагаю вам прочитать http://en.wikibooks.org/wiki/Ada_Programming/Generics

...