用C++实现状态机如何?

Iga*_*tor 3 c++

我是C++的新手.

如何在C++中实现状态机?

我只得到消息,应该知道下一个状态.

我需要使用什么样的结构?

谢谢,伊加尔

Pau*_*l R 17

对于简单的状态机,你可以在循环中使用switch语句,例如

for (;;)
{
    switch (state)
    {

    case STATE_1:
        // do stuff
        // maybe change state
        break;

    case STATE_2:
        // do stuff
        // maybe change state
        break;

    case STATE_3:
        // do stuff
        // maybe change state
        break;

    // ...

    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Peter K.:他没有要求OO解决方案,他没有声明他需要使用特定于C++的语言功能.由于上面的代码是用C++编写的(以及C和Objective C),我认为它符合上述要求.由于这是作业,我假设只需要一个非常简单的状态机. (11认同)
  • 只适用于非常简单的状态机.而且它根本不是OO.您的代码仅限C,不使用C++. (2认同)
  • @Peter K.:美丽是旁观者的眼睛.:-) (2认同)

Pat*_*ick 6

typedef std::pair<State,Message> StateMessagePair;
typedef std::map<StateMessagePair,State> StateDiagram;
StateDiagram sd;
// add logic to diagram
...
State currentState = getInitialState();
...
// process message
Message m = getMessage();
StateDiagram::iterator it=sd.find(std::make_pair(currentState,m)));
if (it==sd.end()) exit("incorrect message");
currentState = it->second;
Run Code Online (Sandbox Code Playgroud)

编辑: 建立状态图是这样完成的(例子是可乐自动售货机):

StateDiagram.insert(std::make_pair(State::Idle           ,Message::MakeChoice   ),State::WaitingForMoney);
StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::Cancel       ),State::Idle);
StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::MoneyEntered ),State::FindCan);
StateDiagram.insert(std::make_pair(State::FindCan        ,Message::CanSentToUser),State::Idle);
Run Code Online (Sandbox Code Playgroud)

可以使用第二个映射实现默认操作,其中键只是State,如下所示:

typedef std::map<State,State> StateDiagramForDefaults;
Run Code Online (Sandbox Code Playgroud)

逻辑可以在StateDiagramForDefaults中执行查找,而不是打印"不正确的消息".

如果需要将动作添加到状态图中,则映射的值应该是一个由动作和新状态组成的对,如下所示:

typedef std::pair<State,Message> StateMessagePair;
typedef std::pair<State,IAction *> StateActionPair;
typedef std::map<StateMessagePair,StateActionPair> StateDiagram;
Run Code Online (Sandbox Code Playgroud)

然后,构建图的逻辑应该"新"实现IAction的类的实例,并将其放在StateDiagram中.

然后,执行逻辑只通过虚拟方法(例如execute()或()-operator)执行IAction实现.


Mir*_*mek 5

标准状态机实现技术是:

  1. 嵌套的switch语句(一些以前的帖子显示了这种技术的例子)
  2. 状态表
  3. GoF State设计模式
  4. 以上的组合

如果您不熟悉状态机并使用C或C++实现,我建议您阅读http://www.ddj.com/184401737上的 Dr.Dobbs文章"返回基础知识" (您需要点击打印链接)顶部方便阅读文本.)

所有标准技术都不适用于分层状态机(例如UML状态图).如果您对现代UML状态机感兴趣,我建议使用我的3部分Embedded.com文章"UML状态机中的速成课程"(http://www.embedded.com/design/testissue/215801043).