C++学习进阶版(一):用C++写简单的状态机实现
目录
一、基础知识
1、状态机
2、四大要素
3、描述方式
4、设计步骤
5、实现过程中需注意
(1) 状态定义
(2) 状态转换规则
(3) 输入处理
(4) 状态机的封装
(5) 状态机的可扩展性和维护性
(6) 避免状态爆炸
(7) 并发和同步
(8) 资源管理
(9) 异常处理
(10) 清晰注释和文档
二、状态机实现
1、绘制状态转移图
2、创建状态转移的FSMIterm类
3、创建有限状态机FSM类
4、测试FSM
5、完整代码
6、测试结果
三、多分支状态机实现
1、需要修改的部分
2、更改输出状态的字符形式表达
3、新增了一个分支选择变量takeGamePath
4、完整代码
5、运行结果
前阵子在改的程序已经暂时告一段落了,现在要和其他同学所做的项目联系起来,其中有一部分涉及到状态机的设计,所以简单写个笔记吧。
参考资料:
什么是状态机?-CSDN博客
c++状态机的使用_c++ 状态机-CSDN博客
一、基础知识
1、状态机
状态机是有限状态自动机(Finite State Machine,FSM)的简称,通过状态图可以清晰表达整个状态的流转。
其中涉及到四个概念:
- 状态(state):指事物的不同状态,一个状态机至少有两个状态。例如一个灯泡,有“亮”和“灭”两种。
- 事件(event):执行某个操作的触发条件或者口令。例如对于事物“灯泡”来说,有“打开开关”和“关闭开关”两个事件。
- 动作(action):事件发生以后要执行动作。例如对于事件“打开开关”,动作就是“开灯”。一般情况下,一个action一般就对应一个函数。
- 转换(transition):从一个状态转变成另一个状态。例如,“开灯过程”就是一个变换。
2、四大要素
- 现态:当前所处状态
- 次态:当条件满足后,即将转移的下一个状态
- 动作:当满足某个事件时执行的动作;动作执行完毕后可以转移到另一个状态或保持原有状态
- 条件:转移状态所需的条件,当满足条件时,会触发一个动作或进行状态转移
3、描述方式
- 状态转移图
- 状态转移表
- HDL描述
4、设计步骤
- 逻辑抽象,得到状态转移图:确定输入、输出、状态变量、画状态转移图;
- 状态简化,得到最简的状态转移图:合并等价状态;
- 状态编码;
- 用C++描述;
5、实现过程中需注意
(1) 状态定义
- 明确定义状态集合,并确保状态之间转换的完备性和一致性。
- 可以使用枚举类型来定义状态,便于理解和管理。
(2) 状态转换规则
- 清晰地定义每个状态下接收哪些输入信号以及接收到这些信号时如何转换到新的状态。
- 使用某种机制(如switch-case、查找表、函数指针等)来实现状态间的转换。
(3) 输入处理
- 确保状态机能正确响应所有有效的输入信号,并且对于无效输入有合适的默认处理策略。
- 如果存在多种输入同时有效的情况,要考虑如何优先级排序或冲突处理。
(4) 状态机的封装
- 将状态机实现封装在一个模块中,隐藏内部状态变化细节,对外暴露接口供其他部分调用。
- 使用私有变量保存当前状态,并通过公共函数改变状态。
(5) 状态机的可扩展性和维护性
- 设计时尽量使状态机易于添加新状态或修改现有状态转换逻辑。
- 使用表驱动(table-driven)方法可以提高代码的可读性和可维护性,尤其是当状态数量较多时。
(6) 避免状态爆炸
- 当状态过多时,要考虑是否存在冗余状态,尝试优化和归并相似状态,以减少状态总数。
(7) 并发和同步
- 若状态机涉及多线程或中断处理,要特别注意状态访问和修改的原子性,可能需要使用互斥锁等同步机制。
(8) 资源管理
- 如果状态机操作伴随着资源(如内存、文件句柄等)的申请和释放,务必在合适的状态转换时完成相应的清理工作,避免资源泄露。
(9) 异常处理
- 确保状态机在发生错误或异常情况下能够恢复到安全状态或报告错误。
(10) 清晰注释和文档
- 详细记录状态机的工作流程、状态转换图以及关键状态和转换的解释,有助于后期维护和他人理解代码。
二、状态机实现
在这里,我借鉴了脚本之家--《C++有限状态机实现详解》中的学生的日常生活示例。
- 事物:学生;
- 学生状态:起床、上学、吃午饭、写作业、睡觉;
- 状态之间需要执行相应的事件进行转移。
1、绘制状态转移图
2、创建状态转移的FSMIterm类
- 枚举所有状态State、所有事件Event;
- 成员变量:现态_curState、事件_event、次态_nextState;
- 成员函数:动作函数
//FSM状态项 class FSMIterm { friend class FSM; //声明 FSM 类为 FSMIterm 类的朋友类 //这意味着 FSM 类可以访问 FSMIterm 类的所有成员,包括私有和保护成员 private: //状态对应的动作函数 static void getup(){ cout
- 详细记录状态机的工作流程、状态转换图以及关键状态和转换的解释,有助于后期维护和他人理解代码。
- 确保状态机在发生错误或异常情况下能够恢复到安全状态或报告错误。
- 如果状态机操作伴随着资源(如内存、文件句柄等)的申请和释放,务必在合适的状态转换时完成相应的清理工作,避免资源泄露。
- 若状态机涉及多线程或中断处理,要特别注意状态访问和修改的原子性,可能需要使用互斥锁等同步机制。
- 当状态过多时,要考虑是否存在冗余状态,尝试优化和归并相似状态,以减少状态总数。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

