iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++有限状态机实现详解
  • 936
分享到

C++有限状态机实现详解

2024-04-02 19:04:59 936人浏览 安东尼
摘要

目录有限状态机四大要素c++函数指针实现总结前提:因为最近打算学设计模式的状态模式,但不是很明白有限状态机和状态模式之间的关系,索性用C++实现了一个简单案例复习了一下FSM,如果有

前提:因为最近打算学设计模式的状态模式,但不是很明白有限状态机和状态模式之间的关系,索性用C++实现了一个简单案例复习了一下FSM,如果有更好的实现方法,欢迎留言

有限状态机四大要素

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

C++函数指针实现

案例:学生的日常生活。

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

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

  • (1)绘制状态转移图
  • (2)创建状态转移的FSMItem类
    • 枚举:所有状态State、所有事件Event;
    • 成员变量:现态_curState、事件_event、次态_nextState
    • 成员函数:动作函数
  • (3)创建有限状态机FSM类
    • 成员变量:状态转移表vector<FSMItem*> _fsmTable
    • 成员函数:初始化状态转移表、状态转移、根据事件执行相应动作
  • (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::State  curState = _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<FSMItem*> _fsmTable;  //状态转移表
};

(4)测试FSM


#include<iOStream>
#include<vector>
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;
}

执行效果:

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C++有限状态机实现详解

本文链接: https://www.lsjlt.com/news/137569.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++有限状态机实现详解
    目录有限状态机四大要素C++函数指针实现总结前提:因为最近打算学设计模式的状态模式,但不是很明白有限状态机和状态模式之间的关系,索性用C++实现了一个简单案例复习了一下FSM,如果有...
    99+
    2022-11-12
  • C++怎么实现一个有限状态机
    本篇内容介绍了“C++怎么实现一个有限状态机”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是有限状态机?简单说就是作一件事可能会经过多个...
    99+
    2023-06-03
  • JS前端实现fsm有限状态机实例详解
    目录引言举个栗子从零开始获取状态状态改变transition实现fsm状态机实现钩子函数完整代码总结引言 我们平时开发时本质上就时对应用程序的各种状态进行切换并作出相应处理,最直接的...
    99+
    2022-11-13
  • 一文详解Go语言中的有限状态机FSM
    目录1、FSM简介1.1 有限状态机的定义1.2 Go中的FSM2、github.com/looplab/fsm 如何使用2.1 fsm 基础使用2.2 fsm 中 Action 何...
    99+
    2023-05-17
    Go语言有限状态机FSM Go 有限状态机 Go FSM
  • React使用有限状态机的实现示例
    目录什么是有限状态机?有限状态机的示例有限状态机和软件开发、计算机科学有什么关系?举了那么多例子,但我该怎么展示在前端开发中使用状态机呢?React 应用程序中的注册表单的传统实现方...
    99+
    2022-11-13
  • C++BoostMetaStateMachine定义状态机超详细讲解
    目录一、说明二、示例和代码一、说明 Boost.MetaStateMachine 用于定义状态机。状态机通过对象的状态来描述对象。它们描述了存在哪些状态以及状态之间可能存在哪些转换。...
    99+
    2022-12-08
    C++ Boost MetaStateMachine C++ MetaStateMachine定义状态机
  • Java实现有限状态机的推荐方案分享
    目录一、背景 二、推荐方式2.1 自定义的枚举 2.2 外部枚举 三、总结 一、背景 平时工作开发过程中,难免会用到状态机(状态的流转)。 如奖学金审批流程、请假审批流程、竞标流程...
    99+
    2022-11-12
  • C语言实现进程5状态模型的状态机
    目录前言什么是状态机定义举例四大概念状态机的应用进程5状态模型实现前言 状态机在实际工作开发中应用非常广泛,在刚进入公司的时候,根据公司产品做流程图的时候,发现自己经常会漏了这样或那...
    99+
    2022-11-13
    C语言 进程5状态模型 状态机 C语言 进程5状态模型 C语言 状态机
  • Qt利用QState状态机实现控件互斥操作详解
    目录功能讲解设置步骤1:设置btn1对应的状态信息2:设置btn2对应的状态信息3:设置btn3对应的状态信息4:设置停止状态5:数据绑定6:将所有的状态添加到状态机QStateMa...
    99+
    2022-12-08
    Qt QState状态机实现控件互斥操作 Qt 控件互斥操作 Qt QState状态机
  • c# 实现打印机状态查询与阻塞打印
    目录打印机状态获取打印机脱机检查打印机阻塞队列实现 在使用winform编写自动打印服务的过程中,发现只要进行了打印命令的调用,文档就会进入到打印等待队列,如果打印机无法正常工作,则...
    99+
    2022-11-12
  • Mobx实现React 应用的状态管理详解
    目录MobX从一个 demo 开始创建类并将其转化成可观察对象使用可观察对象MobX 与 React 集成在组件中使用可观察对象1. 访问全局的类实例2. 通过 props3. 通过...
    99+
    2022-12-08
    Mobx React 应用状态管理 Mobx React
  • SpringSecurity动态权限的实现方法详解
    目录1. 动态管理权限规则1.1 数据库设计1.2 实战2. 测试最近在做 TienChin 项目,用的是 RuoYi-Vue 脚手架,在这个脚手架中,访问某个接口需要什么权限,这个...
    99+
    2022-11-13
  • C# OpenCV实现形状匹配的方法详解
    1. 多角度模板匹配测试效果如下图: 图1-1  图1-2 图1-3 正负角度均可正常识别,识别角度偏差<1° 2. 下面分享一下开发过程: a). R...
    99+
    2022-11-13
  • C++实现动态规划过程详解
    目录C++实现动态规划1. 动态规划的基础2. 动态规划的实现方法3. 实际应用C++实现动态规划 动态规划是解决一类最优问题的常用方法,它是解决最优化问题的一种途径,因为这种算法通...
    99+
    2023-05-20
    C++实现动态规划 C++动态规划
  • C++详解如何实现动态数组
    目录动态数组示例代码运行环境运行效果动态数组 动态数组Vector可以动态扩展内存,其采用连续的内存空间,当内存空间不足,便以原来的容量的2倍或者1.5倍成倍的扩展,将原有的数组元素...
    99+
    2022-11-13
  • Android 详解沉浸式状态栏的实现流程
    目录去掉标题栏效果引入依赖沉浸状态栏颜色沉浸状态栏图片Android—沉浸式状态栏 我们的征程是星辰大海,而非人间烟尘 去掉标题栏 首先去掉对应主题下面的Android自带的Act...
    99+
    2022-11-12
  • vue3如何使用provide实现状态管理详解
    目录前言如何通过 provide/inject 实现 Vuex的功能在应用中注册此插件插件的入口文件创建 store ,把对应的数据挂载到根组件上实现 mapState、mapMut...
    99+
    2022-11-12
  • C语言实现动态顺序表详解
    目录什么是顺序表?1. 定义顺序表结构体:2. 初始化顺序表:3. 销毁顺序表:4. 打印顺序表:5. 判断容量+扩容:6. 头插数据:7. 尾插数据:8. 指定下标位置插入...
    99+
    2022-11-12
  • C++中多态的定义及实现详解
    目录1.多态概念1.1概念2.多态的定义及实现2.1多态的构成条件2.2虚函数2.3虚函数的重写2.4代码示例2.4.1没构成重写2.4.2构成重写2.5虚函数重写的两个例外&nbs...
    99+
    2022-11-12
  • Apache FlinkCEP 实现超时状态监控的步骤详解
      CEP - Complex Event Processing复杂事件处理。 订单下单后超过一定时间还未进行支付确认。 打车订单生成后超过一定时间没有确认上车。 外卖超过预定送达时间一定时限还没有确认送达。 ...
    99+
    2022-06-04
    Apache FlinkCEP apache 超时状态监控
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作