Конечный автомат C++ / Wpmf-конверсия
Я совсем новичок в использовании C++. Я пытаюсь реализовать на C++ конечный автомат, описанный в этой ссылке для языка C: https://barrgroup.com/Embedded-Systems/How-To/Coding- Конечные автоматы.
Я создал класс Fsm, который реализует поведение конечного автомата, и класс Machine, методы которого будут состояниями.
Код работает, но генерирует предупреждение (-Wpmf-conversions), когда я пытаюсь сохранить адрес памяти метода Machine в State state__
class Fsm
{
public:
typedef void (*State)();
private:
State state__;
public:
Fsm(State state);
void dispatch();
};
Fsm::Fsm(State state)
{
state__ = state ;
} //Фсм
void Fsm::dispatch()
{
(*state__)() ;
}
class Machine : public Fsm
{
public:
Machine() : Fsm((State)&Machine::initial) {} // ctor
};
Я использую Atmega2560 с компилятором AVR-GCC.
@ezeg, 👍0
Обсуждение1 ответ
Лучший ответ:
Указатель на функцию-член не допускается в C++. GCC может это разрешить, но жалуется на вас, потому что это нестандартно.
В C++ обычный способ работы с теми вещами, которые вам нужны, — это наследование классов.
Обычно вы создаете базовый класс Fsm
, который реализует базовые функции вашего конечного автомата, а затем накладываете его поверх (создаете новый класс, наследующий Fsm
). code> class) другой класс, реализующий специфические функции вашей машины. Вы можете объявлять функции в базовом классе Fsm
, которые являются чисто виртуальными, то есть они существуют, но не имеют тела. Затем задача дочернего класса состоит в том, чтобы фактически реализовать эту функциональность. Затем родительский класс Fsm
узнает об этих функциях и может их вызывать.
Итак, у вас должно быть что-то вроде:
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(); // --> "Здесь"
Fsm
знает о initial()
, но эта функция еще не определена. Machine
реализует initial()
. Затем вы создаете экземпляр Machine
, который содержит все необходимое. Вызов dispatch()
запускает функцию в родительском классе Fsm
, который затем вызывает initial()
в дочернем Machine
. класс.
- Как писать скетчи, совместимые с makefile?
- Как передать нестатический член класса для обратного вызова на платформах avr?
- GCC msg "note: in definition of macro 'max'" сообщение об ошибке
- Как преобразовать скетч примера Arduino в полный проект C++?
- Работает ли конструкция int array[100] = {0} на Arduino?
- Будет ли .ino-скетч ардуино компилироваться непосредственно на GCC-AVR?
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Работает с gcc, но не с Arduino. ошибка: taking address of temporary array
Для какой строки кода генерируется предупреждение? Кроме того, почему ваш класс Fsm имеет два «общедоступных» спецификатора доступа. И почему type-def (*State)() как недействительный? Возможно, я забыл свой С++, но я не понимаю, что вы пытаетесь здесь сделать., @Paul
@Paul
typedef void (*State)();
— это typedef для указателя функции на функцию без параметров и тип возвращаемого значенияvoid
. Совершенно нормально иметь несколько общедоступных, защищенных или частных разделов в классе., @Majenko«PMF» — это указатель на функцию-член. В C++ это запрещено., @Majenko