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

Jos*_*ssi 0 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;
Run Code Online (Sandbox Code Playgroud)

取消注释时的Builder结果function Create:

type of aggreate cannot be class-wide
Run Code Online (Sandbox Code Playgroud)

我不想要那个错误.

Sim*_*ght 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;
Run Code Online (Sandbox Code Playgroud)

另一种方法是声明一个函数返回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;
Run Code Online (Sandbox Code Playgroud)

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

B4 : Types.Base1 := Types.Create;
B5 : Types.Base2 := Types.Create;
Run Code Online (Sandbox Code Playgroud)

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


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

type Base is abstract tagged record
   Number : Integer := 42;
end record;
Run Code Online (Sandbox Code Playgroud)

或通过函数调用:

type Base is abstract tagged record
   Time : Ada.Calendar.Time := Ada.Calendar.Clock;
end record;
Run Code Online (Sandbox Code Playgroud)