将函数指针传递给函数
Passing a function pointer to a function
如果我想将任何类的非静态成员函数作为按钮的点击函数传递,我应该怎么做?有可能吗?如果是,我该怎么办?例如,在哪个类(这里的EntityToolGUI)中,按钮被初始化,我想将其单击操作设置为该类的非静态成员函数(EntityToolGUI类的非静止成员函数)。
GUIButton.h
typedef void (*ptr2clickFunc)(void);
class GUIButton : public GUIObject {
private : void (*clickFunc)(void);
public : void setClickFunction(ptr2clickFunc clickFunc);
};
GUIButton.cpp
void GUIButton::setClickFunction(ptr2clickFunc clickFunc)
{
this->clickFunc = clickFunc;
}
EntityToolGUI.h
class EntityToolGUI {
public : EntityToolGUI();
protected : void addAnimation();
}
EntityToolGUI.cpp
void EntityToolGUI::addAnimation()
{
cout<<"add animation"<<endl;
}
EntityToolGUI::EntityToolGUI()
{
....
btnAddAnimation->setClickFunction(&EntityToolGUI::addAnimation);
}
我收到一个错误,没有匹配对GUIButton::setClickFunction(void(EntityToolGUI::*)())的函数调用
候选为void GUIButton::setClickFunction(void(*)())
我该如何解决此问题?
传递函数指针的大多数(体面的)C代码都使用额外的void*参数来向函数传递用户上下文。这在C++中并不常见(因为存在比函数指针更好的技术),但如果由于某种原因而无法使用函数指针,那么这可能是合适的。
typedef void (*ptr2clickFunc)(void*);
class GUIButton : public GUIObject {
private : ptr2clickFunc clickFunc;
private : void * userdata;
public : void setClickFunction(ptr2clickFunc clickFunc, void* userdata);
};
class Foo
{
static void do_foo( void * userdata )
{
Foo* thisptr = static_cast<Foo*>(userdata);
thisptr->foo();
}
void foo() { ... }
};
int main()
{
Foo foo;
GUIButton button;
button.setClickFunction( &Foo::do_foo, &foo );
button.click();
}
EDIT正如Bartek所指出的,如果你经常这样做,你可以将静态函数提取到模板中——它看起来有点像这样(未经测试,可能有一些小错误)。
// GUIButton is as before
// Note no static function here
class Foo { void foo(); }
template<typename T, void(T::*FN)() >
void Call( void * data)
{
static_cast<T*>(data)->*FN();
}
int main()
{
Foo f;
GUIButton button;
button.setClickFunction( &Call<Foo,&Foo::foo>, &f );
button.click();
}
如果你想传递obj fun ptr,你可以使用boost::bind和boost::function
http://www.boost.org/doc/libs/1_50_0/libs/bind/bind.html
不能将指向非静态成员函数的指针作为指向"常规"非成员函数的指示器来传递。您应该将addAnimation
设为静态,或者将ptr2clickFunc
typedef设为指向成员函数的指针。
请注意,调用指向成员函数的指针与调用函数指针不同,因为您必须提供要在其上调用成员指针的实例。
addAnimation需要是静态函数。当以现在的方式设置回调函数时,类EntityTollGUI的对象不会与函数一起注册。
试试这个(C++11):
#include <stdio.h>
#include <stdlib.h>
#include <functional>
class Raiser
{
public:
std::function<void(int)> ev1, ev2;
void RaiseEv1()
{
if (!ev1._Empty())
ev1(44);
}
void RaiseEv2()
{
if (!ev2._Empty())
ev2(66);
}
};
class Handler
{
private:
int id;
std::function<void(int)> h;
public:
Handler(int newId)
{
id = newId;
h = [this](int i)
{
printf("Handler with id = %d captured event!n", this->GetId());
};
}
void Hook1(Raiser & raiser)
{
raiser.ev1 = h;
}
void Hook2(Raiser & raiser)
{
raiser.ev2 = h;
}
int GetId()
{
return id;
}
};
int main(int argc, char * argv[])
{
Raiser raiser;
Handler handler1(1), handler2(2);
handler1.Hook1(raiser);
handler2.Hook2(raiser);
raiser.RaiseEv1();
raiser.RaiseEv2();
getchar();
}
AFAIK,这是在不使用语言扩展的情况下用C++中的事件所能得到的最多的结果。
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针