如何使用函数从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
我不想要那个错误。
答案 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;