Реализация C ++ State Machine. Как решить Wpmf-конвекцию Предупреждение? - PullRequest
1 голос
/ 06 ноября 2019

Я пытаюсь реализовать в C ++ конечный автомат, описанный в этой ссылке для языка C: https://barrgroup.com/Embedded-Systems/How-To/Coding-State-Machines.

Я создал класс Fsm, который реализует поведение конечного автомата, икласс Machine, методы которого будут состояниями.

Код работает, но он генерирует предупреждение (-Wpmf-Conversions), когда я пытаюсь сохранить адрес памяти метода Machine в состоянии State __ * 1006. *

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
}; 

Ожидаю устранения предупреждения -Wpmf-Conversions.

1 Ответ

1 голос
/ 06 ноября 2019

State соответствует указателю на функцию.

К сожалению, вы не предоставили определение для initial в своем коде. Так что это небольшая догадка. Но в аргументе вашего конструктора (State)&Machine::initial вы, похоже, предполагаете, что это статическая функция-член.

Это компилируется без ошибок и предупреждений:

class Machine : public Fsm
{
    static void initial();    // make sure it's static 
public:
    Machine() : Fsm((State)&Machine::initial) {}       // ctor
}; 

Теперь, если вы хотите указатель на функцию-членЭто другая история. Во-первых, вам нужно определить State соответственно:

typedef void (Fsm::*State)();

Затем dispatch должен вызвать функцию-член:

void Fsm::dispatch()
{
    (this->*state__)() ;
}

Единственная проблема может заключаться в том, что вы вызываетепроизводный указатель на функцию-член, используя базовый указатель на функцию-член. К счастью, это гарантированно сработает, как объяснено в этом превосходном ответе .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...