良许Linux教程网 干货合集 用C++来实现有限状态机(附代码)

用C++来实现有限状态机(附代码)

这篇文章旨在详细介绍C++有限状态机的相关知识。文中的示例代码提供了详细的说明,具有一定的参考价值。如果你对此感兴趣,可以参考以下内容。

目录:

  1. 有限状态机的四大要素:本节介绍了构成有限状态机的四个核心要素,包括状态、转移条件、转移动作和终止条件。

  2. 使用C++函数指针实现有限状态机:本节示范了使用C++函数指针来实现有限状态机的方法。通过定义不同的状态和转移条件,通过函数指针来触发相应的转移动作。

  3. 总结:文章对C++有限状态机的实现进行了总结,并欢迎读者提出更好的实现方法。

在最近的学习过程中,作者打算学习设计模式中的状态模式。然而,对有限状态机和状态模式之间的关系并不是很了解。因此,作者决定使用C++来实现一个简单的案例,复习了一下有限状态机的概念。如果你对此有更好的实现方法,欢迎在留言中提出。

希望这篇文章对你有所帮助,提供了关于C++有限状态机的相关资料。

有限状态机四大要素

  • 现态:当前所处状态
  • 次态:当条件满足后,即将转移的下一个状态
  • 动作:当满足某个事件时执行的动作;动作执行完毕后可以转移到另一个状态或保持原有状态
  • 条件:转移状态所需的条件,当满足条件时,会触发一个动作或进行状态转移

C++函数指针实现

案例:学生的日常生活。

  • 学生的日常生活包含以下几个状态:起床、上学、吃午饭、做作业、睡觉;
  • 每个状态之间进行转移需要执行相应的事件。

我分为以下几个步骤来实现:

  • (1)绘制状态转移图

  • (2)创建状态转移的FSMItem类

    • 枚举:所有状态State、所有事件Event;
    • 成员变量:现态_curState、事件_event、次态_nextState
    • 成员函数:动作函数
  • (3)创建有限状态机FSM类

    • 成员变量:状态转移表vector _fsmTable
    • 成员函数:初始化状态转移表、状态转移、根据事件执行相应动作
  • (4)测试FSM

(1)绘制状态转移图

image-20240112202213083
image-20240112202213083

(2)FSMItem类

//FSM状态项
class FSMItem
{
    friend class FSM;
private:
     //动作函数
    static void getUp()
{
        cout "student is getting up!" go2School()
{
        cout "student is going to school!" haveLunch()
{
        cout "student is having lunch!" doHomework()
{
        cout "student is doing homework!" sleeping()
{
        cout "student is sleeping!" 

(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::State  curState = _curState;   //现态
        void (*action)() = nullptr;//动作
        FSMItem::State nextState;  //次态
        bool flag = false;
        for (int i = 0; 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 " " is coming..." handleEvent(event);
        cout "fsm current state is " _curState return 0;
}

执行效果:

image-20240112202143124
image-20240112202143124

总结

本篇文章就到这里了,希望能够给你带来帮助,后台回复 状态机 查看状态机的更多内容!

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部