C++-各种回调函数和相关参数写法

1,524 阅读2分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

回调函数

给一个函数传递一个函数指针,在该函数中调用该指针指向的函数,这个被调用的函数称为回调函数。 在学习了可调用对象的概念以后,我们可以传入各种各样的可调用对象,来实现回调功能。

直接上代码

class TestClass
{
public:
	int add(int a, int b) { return a + b; }//public成员函数
};

class TestClass2
{
public:
	static int add(int a, int b) { return a + b; }//静态成员函数
};

class TestClass3
{
public:
	int operator()(int a, int b) { return a + b; }//重载了调用运算符的类
};

int callFunc(int a, int b, int (*p)(int,int)) {//传入函数指针
	return p(a, b);
}

int callFunc2(int a, int b, function<int(int,int)> func) {//传入function类型函数
	return func(a, b);
}

int callFunc3(int a, int b, int (TestClass::*p)(int, int)) {//传入特定类的方法
	TestClass obj;
	return (obj.*p)(a, b);
}

int callFunc4(int a, int b, TestClass3 &callableObj) {//传入可调用对象
	return callableObj(a, b);
}

int add(int a, int b) {//普通函数
	return a + b;
}

cout << callFunc(2, 3, add) << endl;//传入函数,自动转为函数指针,传入&add也可
cout << callFunc(2, 3, [](int a, int b) {return a + b; }) << endl;//传入lambda表达式
cout << callFunc(2, 3, TestClass2::add) << endl;//传入静态成员成员函数
cout << callFunc2(4, 5, bind(add, _1, _2))<<endl;//传入function<int(int,int)>类型的对象
cout << callFunc3(6, 7, &TestClass::add) << endl;//传入类成员函数
TestClass obj;
cout << callFunc2(8, 9, bind(&TestClass::add,&obj,_1,_2))<<endl;//传入function<int(int,int)>类型的对象
TestClass3 obj3;
cout << callFunc4(10, 11, obj3)<<endl;//传入可调用对象
cout << callFunc2(12, 13, bind(&TestClass3::operator(),&obj3,_1,_2))<<endl;//传入function<int(int,int)>类型的对象

通过以上代码我们可以发现,callFunc2形式的函数接口具有很好的通用性,而我们之所以要用回调函数,就是希望多一点“通用性”,让接口调用者决定传入的函数是什么。

callFunc2可以传入任意一种可调用对象进行回调,其参数function<int(int,int)> func表明了其要求的调用形式或者说函数类型。 并且我们可以发现,如果希望成员函数可以用作回调函数,声明为static是最为方便的,因为这时候不需要提前创建一个对象来进行bind,可以直接当作普通函数传入函数接口。

注:尴尬的是,上面例子我写到一半时,被安全软件提示我写的exe是个病毒,估计和回调函数的某些特征有关,直接误报了。