具有持续访问父类型对象的 Ada 记录
Ada record with constant access-to-object-of-parent-type
我最近开始学习 Ada。我想看看是否有可能在 Ada 中创建一个 Boost::Statechart
-like 框架。为此,我需要一个具有常量访问父类型组件对象的记录结构,例如静态指向另一个树节点的树节点,并且 父指针不得在所有时间。像这样:
-- Not working sample
type Node_T is record
Parent : constant access Node_T;
-- error: constant components are not permitted
end record;
-- I wish to create objects of this type like this
Top_Node : Node_T (null);
Child1_Node : Node_T (Top_Node'Access);
Child2_Node : Node_T (Top_Node'Access);
Ada 似乎不支持常量成员字段。所以我求助于使用访问鉴别器:
-- Not working sample
type Node_T (Parent : access Node_T) is null record;
-- error: type declaration cannot refer to itself
但是,使用命名访问类型作为判别有效
type Node_T;
type Ref_Node_T is access all Node_T;
type Node_T (Parent : Ref_Node_T) is null record;
但是,据我了解,这会导致 Node_T
对象的生命周期绑定到 Ref_Node_T
对象的生命周期,而不是另一个父 Node_T
对象的生命周期。这是真的吗?
有没有更好的方法来实现我的需要?
https://www.sigada.org/ada_letters/june2000/sanden.pdf 中描述了另一种创建有限状态机的方法
此解决方案使用受保护对象和任务的组合来实现有限状态机。
FSM 的另一种替代解决方案是使用枚举和数组,如果您需要多个,generic
。
Generic
Type State is (<>); -- Any discrete type.
Type Event is (<>);
Package Finite_State_Machine_Domain is
Type Domain is Array(State, Event) of State;
Generic
Start,
Error : State;
Package Finite_State_Machine is
Type State_Machine is private;
Function Create (State_Map : Domain) return State_Machine;
Function Get_State (Object : in State_Machine) return State;
Procedure Send_Event(Object : in out State_Machine; Transition : in Event);
Private
Type State_Machine is record
Current : State := Start;
State_Map : Domain := (Others => Error);
End record;
End Finite_State_Machine;
End Finite_State_Machine_Domain;
Package Body Finite_State_Machine_Domain is
Package Body Finite_State_Machine is
Function Create (State_Map : Domain) return State_Machine is
( State_Machine'(State_Map => State_Map, Others => <>) );
Function Get_State (Object : in State_Machine) return State is
( Object.Current );
Procedure Send_Event(Object : in out State_Machine; Transition : in Event) is
Begin
if Object.Current /= Error then
Object.Current:= Object.State_Map(Object.Current, Transition);
end if;
End Send_Event;
End Finite_State_Machine;
End Finite_State_Machine_Domain;
我最近开始学习 Ada。我想看看是否有可能在 Ada 中创建一个 Boost::Statechart
-like 框架。为此,我需要一个具有常量访问父类型组件对象的记录结构,例如静态指向另一个树节点的树节点,并且 父指针不得在所有时间。像这样:
-- Not working sample
type Node_T is record
Parent : constant access Node_T;
-- error: constant components are not permitted
end record;
-- I wish to create objects of this type like this
Top_Node : Node_T (null);
Child1_Node : Node_T (Top_Node'Access);
Child2_Node : Node_T (Top_Node'Access);
Ada 似乎不支持常量成员字段。所以我求助于使用访问鉴别器:
-- Not working sample
type Node_T (Parent : access Node_T) is null record;
-- error: type declaration cannot refer to itself
但是,使用命名访问类型作为判别有效
type Node_T;
type Ref_Node_T is access all Node_T;
type Node_T (Parent : Ref_Node_T) is null record;
但是,据我了解,这会导致 Node_T
对象的生命周期绑定到 Ref_Node_T
对象的生命周期,而不是另一个父 Node_T
对象的生命周期。这是真的吗?
有没有更好的方法来实现我的需要?
https://www.sigada.org/ada_letters/june2000/sanden.pdf 中描述了另一种创建有限状态机的方法 此解决方案使用受保护对象和任务的组合来实现有限状态机。
FSM 的另一种替代解决方案是使用枚举和数组,如果您需要多个,generic
。
Generic
Type State is (<>); -- Any discrete type.
Type Event is (<>);
Package Finite_State_Machine_Domain is
Type Domain is Array(State, Event) of State;
Generic
Start,
Error : State;
Package Finite_State_Machine is
Type State_Machine is private;
Function Create (State_Map : Domain) return State_Machine;
Function Get_State (Object : in State_Machine) return State;
Procedure Send_Event(Object : in out State_Machine; Transition : in Event);
Private
Type State_Machine is record
Current : State := Start;
State_Map : Domain := (Others => Error);
End record;
End Finite_State_Machine;
End Finite_State_Machine_Domain;
Package Body Finite_State_Machine_Domain is
Package Body Finite_State_Machine is
Function Create (State_Map : Domain) return State_Machine is
( State_Machine'(State_Map => State_Map, Others => <>) );
Function Get_State (Object : in State_Machine) return State is
( Object.Current );
Procedure Send_Event(Object : in out State_Machine; Transition : in Event) is
Begin
if Object.Current /= Error then
Object.Current:= Object.State_Map(Object.Current, Transition);
end if;
End Send_Event;
End Finite_State_Machine;
End Finite_State_Machine_Domain;