使用函数代替过程来初始化派生类型

时间:2015-04-03 15:14:56

标签: initialization ada derived

如何使用函数从Base类型初始化派生类型?

如果我可以使用function Create代替程序,那会更好看。

procedure Main is

   type Base is abstract tagged record
      Number : Integer;
   end record;

   type Base1 is new Base with null record;
   type Base2 is new Base with null record;

   --function Create return Base'Class is
   --begin
      --return (Number => 1);
   --end;

   procedure Create ( B : out Base'Class ) is
   begin
      B.Number := 1;
   end;

   B1 : Base1;
   B2 : Base2;

begin

   Create (B1);
   Create (B2);

end Main;

取消注释function Create时的构建结果:

type of aggreate cannot be class-wide

我不想要那个错误。

1 个答案:

答案 0 :(得分:5)

只要知道哪个后代,就没有什么能阻止函数返回抽象标记类型的具体后代的实例。您的Create没有。

一种方法是提供一个参数,说明具体的类:

function Create (Kind : Integer) return Base'Class is
begin
   case Kind is
      when 1 =>
         return Base1'(Number => 1);
      when others =>
         return Base2'(Number => Kind);
   end case;
end Create;

另一种方法是声明一个函数返回Base,它必须是abstract,并覆盖派生类型。这必须在一个包中完成(我已经使用了Ada2012功能,如果它很简单,你可以在线编写函数的实现):

package Types is
   type Base is abstract tagged record
      Number : Integer;
   end record;
   function Create return Base is abstract;

   type Base1 is new Base with null record;
   function Create return Base1 is ((Number => 1));

   type Base2 is new Base with null record;
   function Create return Base2 is ((Number => 2));
end Types;

现在,因为在Ada中子程序可以调度函数结果以及参数,你可以写

B4 : Types.Base1 := Types.Create;
B5 : Types.Base2 := Types.Create;

这个问题是你只能使用你在基本功能中指定的参数配置文件。


以上所有假设您希望初始化取决于实际的具体类型。如果不是这样,您可以使用简单的初始化程序初始化为常量值:

type Base is abstract tagged record
   Number : Integer := 42;
end record;

或通过函数调用:

type Base is abstract tagged record
   Time : Ada.Calendar.Time := Ada.Calendar.Clock;
end record;