I read a bachelor thesis with different ways to implement a state machine in c++ and have questions to a piece of code. When I change method StateTable::doNothing from public to protected, then the access to StateTable::doNothing in the initialization of CParser::myTable does not work any more. The compiler gives me the error that doNothing is protected in StateTable. The compiler advice is to use doNothing from CParser. But I did not overloaded doNothing in CParser. So why should I use CParser::doNothing instead of StateTable::doNothing? Thanks in advance! Here is the code:
class StateTable
{
public:
typedef void (StateTable::*Action)();
struct Tran
{
Action action;
unsigned nextState;
};
StateTable(Tran const *table, unsigned nStates, unsigned nSignals)
: myTable(table), myNsignals(nSignals), myNstates(nStates) {}
virtual ~StateTable() {}
void dispatch(unsigned const sig)
{
register Tran const *t = myTable + myState*myNsignals + sig;
(this->*(t->action))();
myState = t->nextState;
}
void doNothing() {}
protected:
unsigned myState;
private:
Tran const *myTable;
unsigned myNsignals;
unsigned myNstates;
};
enum Event {FEEDCHAR_SIG, EOL_SIG, RELEASE_SIG, MAX_SIG};
enum State {EMPTY, COLLECT, FULL, MAX_STATE};
class CParser : public StateTable
{
public:
CParser() : StateTable(&myTable[0][0], MAX_STATE, MAX_SIG) {}
void init()
{
count = 0; myState = EMPTY;
}
int getCount() const
{
return count;
}
private:
void a1()
{
count ++;
}
void a2()
{
count = 0;
}
static StateTable::Tran const myTable[MAX_STATE][MAX_SIG];
int count;
};
StateTable::Tran const CParser::myTable[MAX_STATE][MAX_SIG] =
{
{{static_cast<StateTable::Action>(&CParser::a1), COLLECT },
{&StateTable::doNothing, EMPTY },
{&StateTable::doNothing, EMPTY}},
{{static_cast<StateTable::Action>(&CParser::a1), COLLECT },
{static_cast<StateTable::Action>(&CParser::a2), FULL },
{&StateTable::doNothing, COLLECT }},
{{&StateTable::doNothing, FULL },
{&StateTable::doNothing, FULL },
{static_cast<StateTable::Action>(&CParser::a2), EMPTY }}
};