将状态机的状态作为参数传递给函数指针C++ OOP
Passing states of StateMachine as parameter to a function pointer C++ OOP
我对C++中的函数指针概念相当陌生,所以我不知道如何正确编写我的问题。请耐心等待。
基本上,我正在尝试做的是创建一个 Button 对象,其构造函数接受函数指针作为其参数。 该函数指针指向将更改状态机状态的函数。
这是示例代码(它不起作用,并且不相关的位已被剥离(
按钮.h
#include "StateMachine.h"
class Button
{
private:
void (*m_onclickAction)(); //a data member
public:
Button(void (*action)());
};
StateMachine.h(我没有写它,我只是在获得许可的情况下使用它。所以代码应该没有问题,我不想修改它(
#include <map>
template<class E, class T>
class StateMachine
{
public:
typedef void (T::*CallbackOnInitialise)();
typedef void (T::*CallbackOnExit)();
private:
T* m_pOwner;
E m_currentState;
// Maps to store function pointers to state functions.
std::map<E, CallbackOnInitialise> m_statesOnInitialise;
std::map<E, CallbackOnExit> m_statesOnExit;
public:
StateMachine(T* pOwner, E emptyState)
{
m_currentState = emptyState;
m_pOwner = pOwner;
}
void ChangeState(E statenext)
{
//do something to change the state
}
};
这样在我的主程序课上,我就可以做这样的事情
#include "Button.h"
#include "StateMachine.h"
//Code to instantiate an StateMachine object goes here
Button* aButton = new Button(aStateMachine->ChangeState(NEW_STATE));
问题是我想不出正确传递NEW_STATE的方法,这是在 Program 类中声明的枚举,因为函数指针不需要任何参数。我尝试过调整它,但没有成功。
关于我应该怎么做的任何建议?
你在这里有几个问题。首先,在您的版本中,您在创建Button
实例时调用 ChangeState
成员函数。第二种是m_onclickAction
是指向函数的指针,它与指向成员函数的指针不同。
为此,我建议您研究std::function
和std::bind
:
class Button
{
std::function<void(int)> m_onclickAction;
public:
Button(std::function<void(int)> action) { ... }
};
然后,您可以像这样创建按钮:
Button* aButton = new Button(
std::bind(&StateMachine::ChangeState, aStateMachine, NEW_STATE));
对于回调,boost::bind(( 和 boost::function(( 是一个非常有用的工具。因此,您的 Button 类可能如下所示:
class Button
{
public:
typedef boost::function<void()> Callback;
Button( Callback clickAction );
private:
Callback m_onclickAction; //a data member
};
将带有参数的状态机方法传递给的代码将是:
Button* aButton = new Button( boost::bind( &StateMachine::ChangeState, aStateMachine, NEW_STATE ) );
如果您使用 C++11,您可以将 boost::bind 替换为 std::bind 和 boost::function 替换为 std::function。
Tha 库有一个设计错误。
问题是函数指针只是C++中的函数指针(不是闭包(,因此它没有任何上下文。
如果你想创建一个绘制蓝色圆圈的按钮,你将需要一个全局函数,该函数将绘制一个不带参数的蓝色圆圈。
如果你想要另一个按钮来绘制一个黄色圆圈,你将需要另一个全局函数来绘制一个不带参数的黄色圆圈。
更具体地说,问题是库没有任何方法在按钮中存储所谓的"上下文",以便能够向代码传递用于绘制圆圈的颜色。
C++11 添加了一些东西,提醒了一些闭包(不是真的,因为生命周期问题在没有垃圾回收的情况下很难在任何语言中解决(,但它们不是裸函数指针。
如果不更改 Button
类,你想做的事情是不可能的,除非你使用一些糟糕的 hack,就像你在这里看到的那样,它试图使用裸函数指针在 C 中模拟std::bind
。
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针