【发布时间】:2016-04-14 10:44:38
【问题描述】:
我偶然发现了下面的代码,发现其中的嵌套宏和类型转换非常复杂。
另外,当我尝试编译代码时,我遇到了错误
需要下面代码的解释。
为什么 BEGIN_STATE_MAP 和 END_STATE_MAP 在 Motor.h 中设置为标签,这对我来说真的很新鲜
提前致谢
电机.h
// the Motor state machine class
class Motor : public StateMachine
{
public:
Motor() : StateMachine(ST_MAX_STATES) {}
// external events taken by this state machine
void Halt();
void SetSpeed(MotorData*);
private:
// state machine state functions
void ST_Idle();
void ST_Stop();
void ST_Start(MotorData*);
void ST_ChangeSpeed(MotorData*);
// state map to define state function order
BEGIN_STATE_MAP
STATE_MAP_ENTRY(ST_Idle)
STATE_MAP_ENTRY(ST_Stop)
STATE_MAP_ENTRY(ST_Start)
STATE_MAP_ENTRY(ST_ChangeSpeed)
END_STATE_MAP
// state enumeration order must match the order of state
// method entries in the state map
enum E_States {
ST_IDLE = 0,
ST_STOP,
ST_START,
ST_CHANGE_SPEED,
ST_MAX_STATES
};
};
#endif //MOTOR_H
BEGIN_STATE_MAP 和 END_STATE_MAP 是什么,我发现这个定义真的很新, BEGIN_STATE_MAP 和 END_STATE_MAP 是下面头文件中定义的宏。
StateMachine.h
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
#include <stdio.h>
#include "EventData.h"
struct StateStruct;
// base class for state machines
class StateMachine
{
public:
StateMachine(int maxStates);
virtual ~StateMachine() {}
protected:
enum { EVENT_IGNORED = 0xFE, CANNOT_HAPPEN };
unsigned char currentState;
void ExternalEvent(unsigned char, EventData* = NULL);
void InternalEvent(unsigned char, EventData* = NULL);
virtual const StateStruct* GetStateMap() = 0;
private:
const int _maxStates;
bool _eventGenerated;
EventData* _pEventData;
void StateEngine(void);
};
typedef void (StateMachine::*StateFunc)(EventData *);
struct StateStruct
{
StateFunc pStateFunc;
};
#define BEGIN_STATE_MAP \
public:\
const StateStruct* GetStateMap() {\
static const StateStruct StateMap[] = {
#define STATE_MAP_ENTRY(entry)\
{ reinterpret_cast<StateFunc>(entry) },
#define END_STATE_MAP \
{ reinterpret_cast<StateFunc>(NULL) }\
}; \
return &StateMap[0]; }
#define BEGIN_TRANSITION_MAP \
static const unsigned char TRANSITIONS[] = {\
#define TRANSITION_MAP_ENTRY(entry)\
entry,
#define END_TRANSITION_MAP(data) \
0 };\
ExternalEvent(TRANSITIONS[currentState], data);
#endif
EventData.h
#ifndef EVENT_DATA_H
#define EVENT_DATA_H
class EventData
{
public:
virtual ~EventData() {};
};
#endif //EVENT_DATA_H
虽然我试图编译上面的代码。下面是遇到的错误
错误
-------------- Build: Debug in StateMachine (compiler: GNU GCC Compiler)---------------
mingw32-g++.exe -Wall -fexceptions -g -pedantic -Wzero-as-null-pointer-constant -std=c++0x -Wextra -Wall -c C:\Users\xprk569\StateMachine\main.cpp -o obj\Debug\main.o
In file included from C:\Users\xprk569\StateMachine\main.cpp:2:0:
C:\Users\xprk569\StateMachine\Motor.h: In member function 'virtual const StateStruct* Motor::GetStateMap()':
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:29:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_Idle)
^
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:30:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_Stop)
^
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:31:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_Start)
^
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:32:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_ChangeSpeed)
^
C:\Users\xprk569\StateMachine\StateMachine.h:43:39: error: invalid cast from type 'int' to type 'StateFunc {aka void (StateMachine::*)(EventData*)}'
{ reinterpret_cast<StateFunc>(NULL) }\
^
C:\Users\xprk569\StateMachine\Motor.h:33:5: note: in expansion of macro 'END_STATE_MAP'
END_STATE_MAP
^
Process terminated with status 1 (0 minute(s), 0 second(s))
5 error(s), 0 warning(s) (0 minute(s), 0 second(s))
有人能解释一下为什么宏在 Motor.h 中是这样写的吗? 为什么在 StateMachine.h 和 为什么会抛出错误?
提前致谢
【问题讨论】:
-
“BEGIN_STATE_MAP 和 END_STATE_MAP 是什么” - “是下面头文件中定义的宏。”我猜你自己已经回答过了。
-
避免宏(不要复制古老的MFC)
-
是的,没错。它们是宏,但不能将它们编写为使代码易于理解的函数。我的问题是为什么它们在 Motor.h 中设置为标签,将编辑问题:)
-
无法复制,因为我没有 EventData.h 的副本
-
@Richard:添加 EventData.h。