基本上我有以下课程:
class StateMachine {
...
StateMethod stateA();
StateMethod stateB();
...
};
stateA()和stateB()方法应该能够返回指向stateA()和stateB()的指针。 如何输入定义StateMethod?
答案 0 :(得分:14)
GotW #57表示为此目的使用带隐式转换的代理类。
struct StateMethod;
typedef StateMethod (StateMachine:: *FuncPtr)();
struct StateMethod
{
StateMethod( FuncPtr pp ) : p( pp ) { }
operator FuncPtr() { return p; }
FuncPtr p;
};
class StateMachine {
StateMethod stateA();
StateMethod stateB();
};
int main()
{
StateMachine *fsm = new StateMachine();
FuncPtr a = fsm->stateA(); // natural usage syntax
return 0;
}
StateMethod StateMachine::stateA
{
return stateA; // natural return syntax
}
StateMethod StateMachine::stateB
{
return stateB;
}
这个解决方案主要有三个 优势:
它可以根据需要解决问题。更好的是,它是类型安全的 便携式的。
它的机制是透明的:你得到了自然的语法 调用者/用户,以及自然语法 函数自己的“返回状态A”; 言。
- 醇>
它的开销可能为零:在现代编译器中,代理类, 应有的存储和功能 内联并优化至零。
答案 1 :(得分:8)
只使用typedef:
class StateMachine {
public:
class StateMethod;
typedef StateMethod (StateMachine::*statemethod)();
class StateMethod {
statemethod method;
StateMachine& obj;
public:
StateMethod(statemethod method_, StateMachine *obj_)
: method(method_), obj(*obj_) {}
StateMethod operator()() { return (obj.*(method))(); }
};
StateMethod stateA() { return StateMethod(&StateMachine::stateA, this); }
StateMethod stateB() { return StateMethod(&StateMachine::stateB, this); }
};
答案 2 :(得分:3)
没有'正确'的静态类型,因为完整类型是递归的:
typedef StateMethod (StateMachine::*StateMethod)();
您最好的选择是使用typedef void (StateMachine::*StateMethod)();
,然后执行丑陋的state = (StateMethod)(this->*state)();
PS:boost::function
需要明确的返回类型,至少在我阅读docs时需要boost::function0<ReturnType>
答案 3 :(得分:2)
我的理念是不使用原始成员函数指针。我甚至不知道如何使用原始指针typedef做你想做的事情,语法太可怕了。我喜欢使用boost :: function。
几乎肯定错了:
class X
{
public:
typedef const boost::function0<Method> Method;
// some kind of mutually recursive state machine
Method stateA()
{ return boost::bind(&X::stateB, this); }
Method stateB()
{ return boost::bind(&X::stateA, this); }
};
这个问题肯定比第一次见到眼睛要难得多
答案 4 :(得分:0)
我永远不会记得可怕的C ++函数declspec,所以每当我必须找出描述成员函数的语法时,我就会产生一个故意的编译器错误,它通常会为我显示正确的语法。
所以给出:
class StateMachine {
bool stateA(int someArg);
};
stateA的typedef的语法是什么?不知道..所以让我们试着给它分配一些不相关的东西,看看编译器说的是什么:
char c = StateMachine::stateA
编译说:
error: a value of type "bool (StateMachine::*)(int)" cannot be used to initialize
an entity of type "char"
它是:“bool(StateMachine :: *)(int)”是我们的typedef。