类中的回调函数(收藏)
#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指针的问题.