C ++状态机

时间:2014-05-27 00:38:29

标签: c++ state-machine

下面可能是C ++中简单状态机的实现。类 Tokenizer 维护"标记化状态变量",并返回标记,就像来自字符流的HTML标记一样。

是否有任何理由将Tokenizer类中的函数handle_xxx()移出;

如果是,那么为什么&如何?

#include <iostream>
#include <map>

class Token;
class CharacterReader;

class Tokenizer {
    TokenizerState current_state;
    CharacterReader r;
    std:map<TokenizerState, void (Tokenizer::*pmf)()> stateMap;

public:
    // Tokenizer States
    typedef enum { INITIAL = 0, STATE_1, STATE_2, END } TokenizerState;

    // State Handlers
    void handle_Initial();
    void handle_State_1();
    void handle_State_2();
    // 20 more states before END...
    void handle_End();

    Tokenizer(String text_to_tokenize) 
    {
        stateMap[INITIAL] = handle_Initial;
        stateMap[STATE_1] = handle_State_1;
        stateMap[STATE_2] = handle_State_2;
        stateMap[END] = handle_End;

        current_state = TokenizerState::INITIAL;
        r.set(text_to_tokenize);
    }

    void switchState(TokenizerState s) { current_state = s; }

    void run() {
        while (current_state!=TokenizerState::END) {
            Token token = stateMap[current_state]();
            // do something with the Token
        }
    }
};

void Tokenizer::handle_Initial() {
}

void Tokenizer::handle_State_1() {
    char c = r++;
    switch(c) {
        case 'a':
                break;
        case 'b':
                ts.switchState(Tokenizer::TokenizerState::STATE_2);
    }
}

void Tokenizer::handle_State_2() {
}

void Tokenizer::handle_End() {
}

2 个答案:

答案 0 :(得分:0)

恕我直言,最好的方法是将所有handle_XXX()(将 XXX 作为状态机触发事件)方法移出到单独的接口,并为每个接口提供不同的实现方法已确定的州。 handle_XXX()方法的实现可以接收对当前状态机实例的引用,并对其进行操作/操作(包括触发状态更改)。

这就是众所周知的State Pattern

中提出的内容

我在您的实现中看到的一个当前缺陷是,您错过了映射实际事件以将它们分派给不同的处理程序。

在你提供的基础上继续使用可理解的代码示例是没有意义的。我希望你能指出我的想法。

答案 1 :(得分:-1)

为什么不定义Tokenizer Handler类,并将其实例传递给Tokenizer类?引用成员函数的方法可能仍然有效。

相关问题