函数指针与函数对象

一、函数指针

1、概念:

函数指针指向某种特定类型,声明一个执行函数的指针,只需将指针替换函数名即可

int add(int nLeft,int nRight);//普通函数  

声明:int (*pf) (int,int);//函数指针,pf是指向函数的指针

pf前面有*表示pf是指针,右侧是形参列表表示pf指向的是函数,函数返回类型是int。

2、使用函数指针

指针pf 可以指向具体的add 函数。pf=add;(前提是pf和add的返回类型相同

调用:pf(100,50)-----add(100,50)------(*pf)(100,50)都符合规定

#include <iostream>
using namespace std;
int add(int x, int y)
{
	return x + y;
}

int main()
{
	int(*f)(int x, int y);
	f = add;
	cout << f(1, 2);
	return 0;
}

3、函数指针作为形参

//第二个形参为函数类型,会自动转换为指向此类函数的指针  
Void fuc(int nValue,int pf(int,int));  
  
//等价的声明,显示的将形参定义为指向函数的指针  
Void fuc(int nValue,int (*pf)(int,int));  

调用:func(1,add)-----func(1,pf)

4、返回指向函数的指针

int (*fuc2(int))(int,int);//显示定义  

二、函数对象

引入函数对象

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//全局变量sum
int sum = 0;
//定义全局函数f(int)
void f(int x)
{
	sum += x;
}

int main()
{
	//容器v
	vector<int> v;
	for (int i = 0; i < 100; i++)
	{
		v.push_back(i);
	}
	//函数作为形参
	for_each(v.begin(), v.end(), f);
	cout << sum;
	return 0;
}

为了实现这个求和功能,使用了一个 sum 全局变量,并且 f(int) 是一个全局函数。

随着 C++ 面向对象的思想的普及和发展,绝大多数的功能都封装在了类中,实现模块化编程。那么上述函数将被封装成如下形式:

//类sum
class Sum
{
private:
	int sum;
public:
	//构造函数
	Sum(){ sum = 0; }
	//成员函数
	void f(int x)
	{
		sum += x;
	}
	//成员函数
	int GetSum(){ return sum; }
};

函数对象是重载了 operator() 的类的一个实例,operator() 是函数调用运算符。


class Sum
{
private:
	int sum;
public:
	Sum(){sum=0;}
	void operator()(int x)
	{
		sum+=x;
	}
	int GetSum(){return sum;}
};

注意!与之前的区别在于重载了 operator() 而不是 f() 函数。

则该类的对象成了函数对象

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//类Sum
class Sum
{
private:
	int sum;
public:
	//构造函数
	Sum(){ sum = 0; }
	//函数对象!!!!!
	void operator()(int x)
	{
		sum += x;
	}
	//成员函数
	int GetSum(){ return sum; }
};

int main()
{
	//容器v
	vector<int> v;
	for (int i = 0; i < 100; i++)
	{
		v.push_back(i);
	}
	
	Sum s;
	//sum类的对象成为了函数对象
        //能够和函数名字相匹配的是函数指针int(*op)(int, int)
	s=for_each(v.begin(), v.end(), Sum());
	//成员函数GetSum()
	cout << s.GetSum();
	return 0;
}

优点:

  (1)函数对象有自己的状态,即它可以携带自己的成员函数,而且这个函数对象在多次调用的过程中它的那些状态是共享的,而函数则不能做到这点(除非定义函数内部的静态变量或者全局变量)。

  (2)函数对象有自己的类型,而普通函数则没有。在使用STL的容器时可以将函数对象的类型传递给容器作为参数来实例化相应的模板,从而来定制自己的算法,如排序算法。

        (3)可以用(而且提倡、建议)函数对象来代替函数指针  。函数对象可以在内部修改而不用改动外部接口

猜你喜欢

转载自blog.csdn.net/try_again_later/article/details/81415110
今日推荐