深入C++(3)
函数指针
1.1 初始化与赋值.
只有当赋值操作符左边指针的参数表和返回类型与右边函数或指针的参数表和返回类型完全匹配时,初始化和赋值才正确;
如下面操作可获得一个pFun的函数指针:
int testFun(const int&a, const int &b);
int(*pFun)(const int&, const int &) = testFun;
使用这个函数指针与普通调用函数名方法一致:
pFun(1,2);
1.2 使用typedef来简化函数指针的定义.
使用typedef可以将函数指针包装成一般类型名一样定义,使用方法是
typedef 返回值类型 (*函数类名)(参数1,…);
定义方法:函数类名 函数名 = 某个函数名.
如下面方法定义了一个p1函数指针,并给它赋值为sort_1:
typedef void ( *pFun)(const int&, const int&);
void sort_1(const int&, const int&)
{
cout << "sort_1" << endl;
}
int main()
{
pFun p1 = sort_1;
p1(1, 2);
return 0;
}
1.3 函数指针的数组:
使用了typedef定义函数指针类型后,其数组定义方法与普通类型数组定义方法相同,大体有两种定义方法.
首先假设已经定义了以下函数指针类型和两个用来赋值的函数sort_1和sort_2,:
typedef void ( *pFun)(const int&, const int&);
void sort_1(const int&, const int&)
{
cout << "sort_1" << endl;
}
void sort_2(const int&, const int&)
{
cout << "sort_2" << endl;
}
}
定义方法1
直接定义一个函数指针数组,其存在于栈中,无需分配内存:
int main()
{
pFun pF_1[2];
pF_1[0] = sort_1;
pF_1[1] = sort_2;
int a = 2; int b = 3;
return 0;
}
定义方法2
定义一个指向函数指针的指针,存在于堆中,需要手动申请内存空间,并且需要强转为指定类型:
int main()
{
pFun (*pF_2)[2]; //指针还未被分配内存
pF_2 = (pFun (*)[2])(new pFun[2]);
(*pF_2)[0] = sort_1;
(*pF_2)[1] = sort_2;
return 0;
}
1.4 将函数指针用作函数参数传递
1.4.1先typedef一个函数指针类型,传递两个数字,用来将 比较两个数的大小 的函数赋值给它:
typedef void ( *pFun)(const int&, const int&);
1.4.2先假设有这样一个函数,传递两个整形数,并可以用我们指定的方式来比较大小,而这种自定义方式就需要传递我们自己写的比较函数:
void _max(const int& a, const int &b, pFun pF)
{
pF(a,b);
}
1.4.3接下来是我们定义的两个比较方法,假设sort_1和sort_2是两种不同的比较方式:
void sort_1(const int&, const int&)
{
cout << "sort_1" << endl;
}
void sort_2(const int&, const int&)
{
cout << "sort_2" << endl;
}
1.4.4接下来利用这个类型定义一个新的函数指针,将我们自己写的函数赋值给这个函数指针,并将这两个函数指针作为参数传递给这个_max函数:
int main()
{
pFun pF_1 = sort_1;
pFun pF_2 = sort_2;
int a = 2; int b = 3;
_max(a, b, pF_1);
_max(a, b, pF_2);
return 0;
}
/*
运行结果:
sort_1
sort_2
*/
1.5 extern “C” 函数指针
使用extern “C” 声明的函数指针,其被调用的必须是一个C函数,但在某些C++编译器中,由于编译器的优化作用,其也可以被赋值C++函数,可将其视作C++对C语言的兼容性.
声明方法:
extern "c " void (* fun)(int);
将一个C语言函数exit赋值给这个函数指针:
extern "C" void ( *p)(int) = exit;
调用方法与上述函数指针方法一致.