Generics Ada:具有可变大小数组属性的对象
我想在描述2D离散空间的包中创建一个标记类型,其大小在运行时确定。 (背景:执行a) 我发现的第一个方法是遗传性:Generics Ada:具有可变大小数组属性的对象,generics,ada,dynamic-arrays,Generics,Ada,Dynamic Arrays,我想在描述2D离散空间的包中创建一个标记类型,其大小在运行时确定。 (背景:执行a) 我发现的第一个方法是遗传性: generic Size : Natural; package Worlds is type World_Type is tagged private; type World is access World_Type'Class; subtype Coordinate is Positive range 1..Size; private ty
generic
Size : Natural;
package Worlds is
type World_Type is tagged private;
type World is access World_Type'Class;
subtype Coordinate is Positive range 1..Size;
private
type World_Array is array (Coordinate, Coordinate) of Boolean;
type World_Type is tagged record
Content : World_Array;
end record;
end Worlds;
但是,在为worlds实现访问者时,泛型成为一个大问题:
with Worlds;
package World_Visitors is
type World_Visitor_Type is tagged private;
type World_Visitor is access World_Visitor_Type'Class;
procedure Visite(v : World_Visitor_Type;
w : in out Worlds.World); -- ERROR: invalid prefix in selected component "Worlds"
private
type World_Visitor_Type is tagged null record;
end World_Visitors;
GNAT无法编译它,因为Worlds是一个通用包。
然后,因为我不想为每个可能的世界大小写访问者,所以我尝试C++方式:将大小声明为标记类型的属性。
package Worlds is
type World_Type is tagged private;
type World is access World_Type'Class;
subtype Coordinate is Positive range <>;
function Init(Size : Natural) return World; -- initialize Content attribute as an array of length (Size*Size)
private
type World_Array is array (Coordinate, Coordinate) of Boolean;
type World_Type is tagged record
Content : World_Array;
Size : Natural;
end record;
end Worlds;
包世界是
类型World\u类型标记为private;
世界类型是访问世界类型的类;
子类型坐标为正范围;
函数Init(大小:Natural)返回世界;——将内容属性初始化为长度数组(大小*大小)
私有的
类型World_Array是布尔值的数组(坐标、坐标);
类型世界\类型被标记为记录
内容:世界_阵列;
尺寸:天然;
结束记录;
世界末日;
当然,这是行不通的,因为World_数组需要一个明确的坐标范围。
事实上,我不知道如何在标记类型中创建运行时选择大小的数组。
我从或那里得到了一些想法,但在这种情况下似乎没有什么意义
Ada如何实现具有可变大小数组属性的对象?过程访问(v:World\u Visitor\u Type;
w:在外面的世界里。世界)错误:所选组件“Worlds”中的前缀无效
这是行不通的——这是因为Worlds是一个通用的包,从类型上看,实际上没有Worlds.World这样的东西。(这意味着参数w
的类型永远无法与实例化匹配。)
解决这一问题的一种方法是使用Worlds作为参数使World\u访问者
通用。像这样:
通用
X:阳性;
包装温度为
子类型索引为整数范围1..X;
终端温度;
通用的
对于包K,是新的temp();
程序包温度取决于
--注意,参数I现在可以通过形式参数K依赖于temp。
函数J(I:K.索引)返回布尔值为(True);
终端温度取决于;
另一种方法是将访问者转移到Worlds包中。
另一种方法是让访问者的包成为世界之子。解决此问题的正常Ada方法是使用判别法(请参阅) 在你的情况下,这看起来像
包世界是
类型World_type(大小:Natural)标记为private;
类型World是访问世界\u type'Class;--“”要解决如此多的颜色错误
私有的
类型World_Array是布尔值的数组(正范围,正范围);
类型世界\类型(大小:自然)标记为记录
内容:世界_数组(1.大小,1.大小);
结束记录;
世界末日;
其中,World\u Array
是无约束数组类型()的一个示例。你可以通过这样的代码创建一个新世界
W:Worlds.World:=newworlds.World\u类型(大小=>100);
请注意,创建对象后,无法更改大小
我遗漏了坐标
;而且您可能不需要Init
,特别是如果您为内容提供了一个初始值设定项
:
Content:World\u数组(1..Size,1..Size):=
(其他=>(其他=>错误));
编辑26.iii.15:Code正在创建一个大小为
size+1
xsize+1
的数组,或者将其作为一个子包。是否有办法允许重新分配内容(例如,达到更大的大小),或者有必要在新世界中操作一个世界的明确副本?使用此方案,您无法重新分配,你只能复制。您可以使内容
成为对世界数组
的访问,在这种情况下,您不需要鉴别器,但需要初始化
;这将允许重新分配。您必须进行内存管理,这在理想情况下是通过从Ada.Finalization.Controlled
(或Limited\u Controlled
)派生World\u Type
)并实现Finalization
。