我有两个问题:第一个是我试图解决的具体错误的原因,第二个是我解决问题的方法的有效性。
我正试图创建一个使用成员函数指针的状态机,但我在细节中迷失了方向。成员函数指针主题中的其他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/