用C++來實現(xiàn)有限狀態(tài)機(附代碼)
來源:網(wǎng)絡(luò)素材
整理:李肖遙
這篇文章主要為大家詳細介紹了C++有限狀態(tài)機的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
目錄
有限狀態(tài)機四大要素
C++函數(shù)指針實現(xiàn)
總結(jié)
前提:因為最近打算學(xué)設(shè)計模式的狀態(tài)模式,但不是很明白有限狀態(tài)機和狀態(tài)模式之間的關(guān)系,索性用C++實現(xiàn)了一個簡單案例復(fù)習(xí)了一下FSM,如果有更好的實現(xiàn)方法,歡迎留言
有限狀態(tài)機四大要素
現(xiàn)態(tài):當(dāng)前所處狀態(tài)
次態(tài):當(dāng)條件滿足后,即將轉(zhuǎn)移的下一個狀態(tài)
動作:當(dāng)滿足某個事件時執(zhí)行的動作;動作執(zhí)行完畢后可以轉(zhuǎn)移到另一個狀態(tài)或保持原有狀態(tài)
條件:轉(zhuǎn)移狀態(tài)所需的條件,當(dāng)滿足條件時,會觸發(fā)一個動作或進行狀態(tài)轉(zhuǎn)移
C++函數(shù)指針實現(xiàn)
案例:學(xué)生的日常生活。
學(xué)生的日常生活包含以下幾個狀態(tài):起床、上學(xué)、吃午飯、做作業(yè)、睡覺;
每個狀態(tài)之間進行轉(zhuǎn)移需要執(zhí)行相應(yīng)的事件。
我分為以下幾個步驟來實現(xiàn):
(1)繪制狀態(tài)轉(zhuǎn)移圖
(2)創(chuàng)建狀態(tài)轉(zhuǎn)移的FSMItem類
枚舉:所有狀態(tài)State、所有事件Event;
成員變量:現(xiàn)態(tài)_curState、事件_event、次態(tài)_nextState
成員函數(shù):動作函數(shù)
(3)創(chuàng)建有限狀態(tài)機FSM類
成員變量:狀態(tài)轉(zhuǎn)移表vector<FSMItem*> _fsmTable
成員函數(shù):初始化狀態(tài)轉(zhuǎn)移表、狀態(tài)轉(zhuǎn)移、根據(jù)事件執(zhí)行相應(yīng)動作
(4)測試FSM
(1)繪制狀態(tài)轉(zhuǎn)移圖

(2)FSMItem類
//FSM狀態(tài)項class FSMItem{friend class FSM;private://動作函數(shù)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://枚舉所有狀態(tài)enum State{GETUP = 0,GOTOSCHOOL,HAVELUNCH,DOHOMEWORK,SLEEP};//枚舉所有事件enum Events{EVENT1 = 0,EVENT2,EVENT3};public://初始化構(gòu)造函數(shù)FSMItem(State curState, Events event, void(*action)(), State nextState):_curState(curState), _event(event), _action(action), _nextState(nextState) {}private:State _curState; //現(xiàn)態(tài)Events _event; //條件void (*_action)(); //動作State _nextState; //次態(tài)};
(3)FSM類
class FSM{public://初始化狀態(tài)機FSM(FSMItem::State curState= FSMItem::GETUP):_curState(curState){initFSMTable();}//狀態(tài)轉(zhuǎn)移void transferState(FSMItem::State nextState){_curState = nextState;}//根據(jù)當(dāng)前狀態(tài)和發(fā)生的事件,執(zhí)行相應(yīng)的動作,并進行狀態(tài)轉(zhuǎn)移void handleEvent(FSMItem::Events event){FSMItem::State curState = _curState; //現(xiàn)態(tài)void (*action)() = nullptr;//動作FSMItem::State nextState; //次態(tài)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;}}//找到對應(yīng)的狀態(tài)項,執(zhí)行動作,轉(zhuǎn)移狀態(tài)if (flag){if (action){action();}transferState(nextState);}}private://根據(jù)畫的狀態(tài)轉(zhuǎn)移圖初始化狀態(tài)轉(zhuǎn)移表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; //現(xiàn)態(tài)private:vector<FSMItem*> _fsmTable; //狀態(tài)轉(zhuǎn)移表};
(4)測試FSM
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;}
執(zhí)行效果:
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,后臺回復(fù) 狀態(tài)機 查看狀態(tài)機的更多內(nèi)容!
???????????????? END ???????????????
關(guān)注我的微信公眾號,回復(fù)“加群”按規(guī)則加入技術(shù)交流群。
點擊下面圖片,有星球具體介紹,新用戶有新人優(yōu)惠券,老用戶半價優(yōu)惠,期待大家一起學(xué)習(xí)一起進步。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。

