I'm quite a newbie using C ++. I am trying to implement in C ++, the state machine described in this link for C language: https://barrgroup.com/Embedded-Systems/How-To/Coding-State-Machines.
I have created an Fsm class, which implements the behavior of the state machine, and a Machine class, whose methods will be the states.
The code works, but it generates a warning (-Wpmf-conversions) when I try to save the memory address of a Machine method, in State state__
class Fsm
{
public:
typedef void (*State)();
private:
State state__;
public:
Fsm(State state);
void dispatch();
};
Fsm::Fsm(State state)
{
state__ = state ;
} //Fsm
void Fsm::dispatch()
{
(*state__)() ;
}
class Machine : public Fsm
{
public:
Machine() : Fsm((State)&Machine::initial) {} // ctor
};
I'm using an Atmega2560, with AVR-GCC compiler.
1 Answer 1
A pointer to a member function is not allowed in C++. GCC can allow it, but moans at you because it's non-standard.
In C++ the normal way of dealing with the kind of thing you want is through class inheritance.
Typically you would create your base Fsm
class that implements the basic functionality of your state machine control, then overlay over the top of that (create a new class that inherits the Fsm
class) another class that implements your specific machine functionality. You can declare functions in your base Fsm
class that are pure virtual - that is, they exist, but have no body. It's then the job of the child class to actually implement that functionality. The parent Fsm
class then knows about those functions and can call them.
So you would have something like:
class Fsm {
public:
void dispatch();
protected:
virtual void initial() = 0;
};
void Fsm::dispatch() {
initial() ;
}
class Machine : public Fsm {
protected:
void initial() {
Serial.println("Here");
}
};
Machine mach;
mach.dispatch(); // --> "Here"
Fsm
knows about initial()
, but the function hasn't been further defined. Machine
implements initial()
. You then create an instance of Machine
which contains everything needed. Calling dispatch()
runs the function in the Fsm
parent class which then calls initial()
in the child Machine
class.
typedef void (*State)();
is a typedef for a function pointer to a function with no parameters and avoid
return type. It is perfectly normal to have multiple public, protected or private sections in a class.