基本上我有以下课程:
class StateMachine {
...
StateMethod stateA();
StateMethod stateB();
...
};
stateA() 和 stateB() 方法应该能够返回指向 stateA() 和 stateB() 的指针。如何键入定义StateMethod?
基本上我有以下课程:
class StateMachine {
...
StateMethod stateA();
StateMethod stateB();
...
};
stateA() 和 stateB() 方法应该能够返回指向 stateA() 和 stateB() 的指针。如何键入定义StateMethod?
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;
}
该解决方案具有三个主要优势:
它可以根据需要解决问题。更好的是,它是类型安全且可移植的。
它的机制是透明的:您可以获得调用者/用户的自然语法,以及函数自己的“return stateA;”的自然语法;陈述。
它的开销可能为零:在现代编译器上,代理类及其存储和函数应该内联并优化到零。
仅使用 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); }
};
编辑:njsf 在这里证明我错了。但是,您可能会发现静态转换更易于维护,因此我将把其余部分留在这里。
由于完整类型是递归的,因此没有“正确”的静态类型:
typedef StateMethod (StateMachine::*StateMethod)();
你最好的选择是使用typedef void (StateMachine::*StateMethod)();
然后做丑陋的state = (StateMethod)(this->*state)();
PS:boost::function
需要一个明确的返回类型,至少从我对文档的阅读来看:boost::function0<ReturnType>
我的理念是不要使用原始成员函数指针。我什至不知道如何使用原始指针 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); }
};
这个问题肯定比第一次见到要困难得多
我永远记不起可怕的 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。