(一) 函数指针
1.定义
顾名思义,函数指针为指向函数的指针。如同指向基本数据类型如int,char,float等的指针一样,函数指针存储所指向函数的地址,因此通过函数指针,当然能够调用所指向的函数。
函数指针的用途有两个:调用函数和做函数的参数。
函数指针的声明如下:
函数返回值 (*指针变量名)(形参列表);
需要注意的是,*指针变量名的括号不能省略。因为操作符()的运算优先级比*高,函数指针声明就会变成返回值为指针的函数声明。
2.举例
#include <iostream>
using namespace std;
bool smaller(int const& a, int const& b)
{
cout << "smaller int version is called." << endl;
return a<b;
}
bool smaller(double const& a, double const& b)
{
cout << "smaller double version is called." << endl;
return a<b;
}
int main(int argc, char *argv[])
{
int inta = 10, intb = 20;
double dba = 1.22, dbb = 0.232;
bool (*pFunc1)(int const&, int const&) = smaller;
bool (*pFunc2)(double const&, double const&) = smaller;
bool result = pFunc1(inta, intb);// call int version
result = pFunc2(dba, dbb);// call double version
system("PAUSE");
return 0;
}
(二) 函数对象
1.定义
函数对象是重载了操作符()的普通类对象,C++实现回调函数的一种方法。
虽然函数指针广泛应用于回调函数的实现,但是用函数对象替换函数指针有如下优势:
(1) 设计更灵活,更具有弹性
因为对象可以在内部修改,而不用修改外部接口;而且函数对象能够存储先前调用结果的数据成员。在使用普通函数时需要将调用结果存储在全局或本地静态变量中, 这会产生一些潜在的缺陷。
(2) 函数对象在编译器中能实现内联调用,提高编译性能;函数指针无法实现。
2.举例
函数对象的定义
template<class T>
class Adder
{
public:
const T operator()(T const& a, T const& b){
return a+b;
}
};
定义callback函数测试函数对象,接受三个参数,前两个为T类型的数据引用,第三个为回调函数引用。
template<class T, class Func>
const T callback(T const& a, T const& b, Func& func){
return func(a, b);
}
在main函数中编写测试代码如下:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Adder<int> adder;
int sum = callback<int>(10, 20, adder);
//sum = callback<int>(10, 20, Adder<int>()); // shall be ok, too
cout << "sum = " << sum << endl;
system("PAUSE");
return 0;
}
函数对象通常不定义构造函数和析构函数,编译器自动使用默认的构造和析构函数,因此在创建和销毁过程中不需要关注太多细节。