类中的回调函数(收藏) #1 回调函数是函数的一种,都有一样的声明和定义格式。 回调函数是其他函数中的参数。也就是说其函数地址作为其他函数的参数。 我是这样理解的。 回调函数不同的地方有不同的使用方法,一般很少用到,API里常用。 回调 原文CALLBACK。
简单来说,当你调用一个函数包含如下的入口参数时, fun(MYFUN* fun1,.....)的时候,我们就可以将函数指针fun1叫做回调函数。 这么叫的原因也很简单。你调用fun的时候,fun又回过来调用了fun1。故称fun1为回调函数。 所以回调函数只是一个函数指针,她有主调函数在用户调用时自动调用。
#2 但是在class中用回调函数就有以下限制: 回调函数和主调函数一般为全局函数或者是static函数. 原因在于非static函数有一个隐含的this指针!
例在类中使用回调函数(调类的成员函数): #include<iostream> using namespace std;
class x{ public: int fn1(int) { return 1; } int fn2(int) { return 2; } void backcall(int i, int(*p)(int)) { cout<<p(i)<<endl; } };
int main() { x x1; x1.backcall(10,x1.fn1) ; //error:cannot convert parameter 2 from 'int (int)' to 'int (__cdecl *)(int)' x1.backcall(2,x1.fn2) ; //和上面相同.
return 0; } 如你所见,程序出错了.理由就是不能把int (int)转换成int(__cdecl *)(int), 这是为什么呢? 函数名本身不就代表一个地址吗? 不是可以赋给函数指针的吗?
#3 至于为什么这样?这点我也不是很清楚,但猜想是由于this指针所引起的. fn1和fn2中都有一个this指针, 而int (*p)(int)没有! 所以,把fn1和fn2声明成全局函数或static函数(强制去掉this指针) 就没问题了. 代码就不贴出来了,呵呵.
#4 解决方案 既然fn1和fn2是有this指针的,那么我们修改一下backcall, 给它加上this指针如何? 如下: #include<iostream> using namespace std;
class x { public: int fn1(int) { return 1; } int fn2(int) { return 2; } void backcall(int i, int(x::*p)(int)) { cout<<(this->*p)(i)<<endl; } };
int main() { x x1; x1.backcall(10,x1.fn1) ; x1.backcall(2,x1.fn2) ;
return 0; } 这样就解决了this指针的问题. |
|