我有两个问题:第一个是我试图解决的具体错误的原因,第二个是我解决问题的方法的有效性。
我正试图创建一个使用成员函数指针的状态机,但我在细节中迷失了方向。成员函数指针主题中的其他Q/As似乎涉及从类外调用成员函数,并提倡使用std::function和std::bind。我还阅读了the C++ FAQ on pointers to member functions一文,其中还提供了在类之外调用成员函数的示例。我不完全确定这些例子是否适用于我所要做的事情。
这种状态机方法在我为这个嵌入式应用程序所做的工作中是通用的(这是我用C++编写的第一个实际应用程序)。如果这种方法是愚蠢的,请帮助我找到更好的解决方法。下面的特定代码是针对MessageHandler类的。其思想是每个硬件通信端口ISR将其内容复制到自己的缓冲区,然后将自己的MessageHandler对象排队以进行处理。有几个通信接口,但所有接口上的协议都是相同的。
来自MessageHandler.h的一些片段:

class MessageHandler
{
private:
    enum state_t {
        WAIT_METADATA,
        WAIT_PAYLOAD,
        NUM_STATES
    };
    enum transfer_t {
        INPUT_PARTIAL_METADATA,
        INPUT_METADATA,
        INPUT_PARTIAL_PAYLOAD,
        INPUT_COMMAND,
        INPUT_TIMEOUT,
        INPUT_UNKNOWN,
        NUM_TRANSFER_INPUTS
    };

    typedef transfer_t (MessageHandler::*transferFunction)();
    transferFunction transferFunctionTable[NUM_STATES] = {
        checkMetadata,
        checkPayload
    };

    typedef state_t(MessageHandler::*stateFunction)();
    stateFunction stateFunctionTable[NUM_TRANSFER_INPUTS] = {
        gotPartialMetadata,
        gotMetadata,
        gotPartialPayload,
        gotCommand,
        gotTimeout,
        gotUnknownError
    };

    size_t processTable[NUM_TRANSFER_INPUTS][NUM_STATES] = {
        { 0, 5 },
        { 1, 5 },
        { 5, 2 },
        { 5, 3 },
        { 4, 4 },
        { 5, 5 }
    };

    ...

    state_t state;

    transfer_t getInput();
    transfer_t checkMetadata();
    transfer_t checkPayload();
    state_t gotPartialMetadata();
    state_t gotMetadata();
    state_t gotPartialPayload();
    state_t gotCommand();
    state_t gotTimeout();
    state_t gotUnknownError();

    ...

public:
    ...
    state_t process();

};

以及来自MessageHandler.cpp的一些示例:
MessageHandler::transfer_t MessageHandler::getInput()
{
    ...
    return transferFunctionTable[state]();
}

来自MessageHandler.cpp的另一个:
MessageHandler::state_t MessageHandler::process()
{
    do {
        state = stateFunctionTable[ processTable[getInput()][state] ]();
    } while (cbRemaining > 0);
}

我不明白为什么对于我提供的两个成员函数,函数表调用会出错:
Error: expression preceding parentheses of apparent call must have (pointer-to-) function type
这不是我提供的吗?也就是说,transferFunctionTable和stateFunctionTable的类型如何不是指向函数的指针?
我认为要解决这个问题,必须使所有函数都是静态的,并将引用/指针传递给MessageHandler对象。
提前谢谢你的帮助。

最佳答案

MessageHandler::transfer_t MessageHandler::getInput()
{
    return transferFunctionTable[state]();
}

应该是
MessageHandler::transfer_t MessageHandler::getInput()
{
    return (this->*transferFunctionTable[state])();
}

关于c++ - FSM在C++中使用成员函数指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23915387/

10-11 21:14