C++有限状态机实现详解
目录
- 有限状态机四大要素
- C++函数指针实现
- 总结
有限状态机四大要素
- 现态:当前所处状态
- 次态:当条件满足后,即将转移的下一个状态
- 动作:当满足某个事件时执行的动作;动作执行完毕后可以转移到另一个状态或保持原有状态
- 条件:转移状态所需的条件,当满足条件时,会触发一个动作或进行状态转移
C++函数指针实现 案例:学生的日常生活。
- 学生的日常生活包含以下几个状态:起床、上学、吃午饭、做作业、睡觉;
- 每个状态之间进行转移需要执行相应的事件。
- (1)绘制状态转移图
- (2)创建状态转移的FSMItem类
- 枚举:所有状态State、所有事件Event;
- 成员变量:现态_curState、事件_event、次态_nextState
- 成员函数:动作函数
- (3)创建有限状态机FSM类
- 成员变量:状态转移表vector
_fsmTable - 成员函数:初始化状态转移表、状态转移、根据事件执行相应动作
- 成员变量:状态转移表vector
- (4)测试FSM
(1)绘制状态转移图
文章图片
(2)FSMItem类
//FSM状态项class FSMItem{friend class FSM; private://动作函数static void getUp(){cout << "student is getting up!" << endl; }static void go2School(){cout << "student is going to school!" << endl; }static void haveLunch(){cout << "student is having lunch!" << endl; }static void doHomework(){cout << "student is doing homework!" << endl; }static void sleeping(){cout << "student is sleeping!" << endl; }public://枚举所有状态enum State{GETUP = 0,GOTOSCHOOL,HAVELUNCH,DOHOMEWORK,SLEEP}; //枚举所有事件enum Events{EVENT1 = 0,EVENT2,EVENT3}; public://初始化构造函数FSMItem(State curState, Events event, void(*action)(), State nextState):_curState(curState), _event(event), _action(action), _nextState(nextState) {}private:State_curState; //现态Events_event; //条件void(*_action)(); //动作State_nextState; //次态};
(3)FSM类
class FSM{public://初始化状态机FSM(FSMItem::State curState= FSMItem::GETUP):_curState(curState){initFSMTable(); }//状态转移void transferState(FSMItem::State nextState){_curState = nextState; }//根据当前状态和发生的事件,执行相应的动作,并进行状态转移void handleEvent(FSMItem::Events event){FSMItem::StatecurState = _curState; //现态void (*action)() = nullptr; //动作FSMItem::State nextState; //次态bool flag = false; for (int i = 0; i < _fsmTable.size(); i++){if (event == _fsmTable[i]->_event && curState == _fsmTable[i]->_curState){flag = true; action = _fsmTable[i]->_action; nextState = _fsmTable[i]->_nextState; break; }}//找到对应的状态项,执行动作,转移状态if (flag){if (action){action(); }transferState(nextState); }}private://根据画的状态转移图初始化状态转移表void initFSMTable(){_fsmTable.push_back(new FSMItem(FSMItem::GETUP, FSMItem::EVENT1, &FSMItem::getUp, FSMItem::GOTOSCHOOL)); _fsmTable.push_back(new FSMItem(FSMItem::GOTOSCHOOL, FSMItem::EVENT2, &FSMItem::go2School, FSMItem::HAVELUNCH)); _fsmTable.push_back(new FSMItem(FSMItem::HAVELUNCH, FSMItem::EVENT3, &FSMItem::haveLunch, FSMItem::DOHOMEWORK)); _fsmTable.push_back(new FSMItem(FSMItem::DOHOMEWORK, FSMItem::EVENT1, &FSMItem::doHomework, FSMItem::SLEEP)); _fsmTable.push_back(new FSMItem(FSMItem::SLEEP, FSMItem::EVENT2, &FSMItem::sleeping, FSMItem::GETUP)); }public:FSMItem::State _curState; //现态private:vector_fsmTable; //状态转移表};
(4)测试FSM
#include#include using namespace std; //测试事件变换void testEvent(FSMItem::Events& event){switch (event){case FSMItem::EVENT1:event = FSMItem::EVENT2; break; case FSMItem::EVENT2:event = FSMItem::EVENT3; break; case FSMItem::EVENT3:event = FSMItem::EVENT1; break; }}int main(){FSM *fsm = new FSM(); auto event = FSMItem::EVENT1; while (1){cout << "event " << event << " is coming..." << endl; fsm->handleEvent(event); cout << "fsm current state is " << fsm->_curState << endl; testEvent(event); }return 0; }
执行效果:
文章图片
总结 【C++有限状态机实现详解】本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- Java基础-高级特性-枚举实现状态机
- [丰声]简字·第14期|[丰声]简字·第14期 精要主义(有限时间精力只用于有意义的事)
- c++基础概念笔记
- 牛逼!C++开发的穿越丛林真人游戏,游戏未上线就有百万人气
- C++Primer之|C++Primer之 函数探幽
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- QML基础信息
- C++-类型转换