0
点赞
收藏
分享

微信扫一扫

C++仿函数【C++仿函数】

爱情锦囊 2022-03-15 阅读 191

仿函数

把类对象像函数名一样使用,所认称为仿函数,仿函数本质不是函数而是类对象。

仿函数(functor)就是使一个类,使用看上去像一个函数。实现就是类中实现一个operator(),这个类就有了类似函数的行为,这个类就是一个仿函数类了。

operator( ) 语法格式

class 类名
{
	返值类型 operator()(参数类型)
	函数体
}

使用仿函数实现求幂运算

代码演示:

#include <iostream>
#include <math.h>
using namespace std;

class Pop
{
public:
	double operator()(double x, int y)
	{
		int resu = 1;
		for (int tmp = 0; tmp < y; tmp++)
			resu *= x;
		return resu;
	}
};

int main()
{
	int a = 5;
	cout << pow(a,2) << endl;	//系统提供的函数接口

	Pop mypow;
	cout << mypow(a, 2) << endl;	//仿函数实现
	//等价于mypow.operator()(a, 2)

	return 0;
}

运行结果:
运行结果
我们可以到上面生成的类对象以函数的形式使用。这种现象就叫做仿函数。
其本质是实现 ( ) 重载。

std::sort 中回调函数

简单引入vector

#include <iostream>
#include <math.h>
#include <algorithm>		//算法
#include <vector>			//STL-vector
using namespace std;

int main()
{
	int arr[6] = {1,3,5,8,6,4};
	vector<int> vi(arr, arr + 6);	
	/*
	* vector			模板
	* vector<int>		模板实例化    也就是 类
	* vector<int> vi	类生成对象
	* vector<int> vi(arr, arr + 6);		类生成对象的入参
	*/	

	vector<int>::iterator itr;		
	for (itr = vi.begin(); itr != vi.end(); ++itr)//C++98标准打印数组
	{
		cout << *itr << endl;
	}

	cout << "=================================="<<endl;

								
	for (auto itr = vi.begin(); itr != vi.end(); ++ itr)//C++11标准打印数组
	{
		cout << *itr << endl;
	}
	cout << "==================================" << endl;

									
	for (auto i : vi)		//C++11标准打印数组
	{
		cout << i << endl;
	}
	return 0;
}

运行结果:
运行结果
代码演示:

#include <iostream>
#include <math.h>
#include <algorithm>		//算法
#include <vector>			//STL-vector
using namespace std;


bool myCompare(int a, int b)
{
	return a > b;
}


int main()
{
	int arr[6] = {1,3,5,8,6,4};
	vector<int> vi(arr, arr + 6);	
	/*
	* vector			模板
	* vector<int>		模板实例化    也就是 类
	* vector<int> vi	类生成对象
	* vector<int> vi(arr, arr + 6);		类生成对象的入参
	*/	


	sort(vi.begin(),vi.end(), myCompare);	//排序
	vector<int>::iterator itr;		
	for (itr = vi.begin(); itr != vi.end(); ++itr)//C++98标准打印数组
	{
		cout << *itr << endl;
	}
	return 0;
}

运行结果为:
运行结果
我们可以看到实现了排序。
但是C++中这种方法不被看好,因为有更好的方法:
代码演示:

#include <iostream>
#include <math.h>
#include <algorithm>		//算法
#include <vector>			//模板
using namespace std;


bool myCompare(int a, int b)
{
	return a > b;
}


class Compare
{
public:
	bool operator()(int a, int b)
	{
		return a > b;
	}
};

int main()
{
	int arr[6] = {1,3,5,8,6,4};
	vector<int> vi(arr, arr + 6);	
	/*
	* vector			模板
	* vector<int>		模板实例化    也就是 类
	* vector<int> vi	类生成对象
	* vector<int> vi(arr, arr + 6);		类生成对象的入参
	*/	

	Compare c;	//生成类对象
	sort(vi.begin(),vi.end(), c);	//排序
	//等价于sort(vi.begin(),vi.end(), c.operator());

	vector<int>::iterator itr;		
	for (itr = vi.begin(); itr != vi.end(); ++itr)//C++98标准打印数组
	{
		cout << *itr << endl;
	}
	return 0;
}

运行结果为:
运行结果

换一种写法,直接传递匿名对象:
代码演示:

#include <iostream>
#include <math.h>
#include <algorithm>		//算法
#include <vector>			//模板
using namespace std;


bool myCompare(int a, int b)
{
	return a > b;
}


class Compare
{
public:
	bool operator()(int a, int b)
	{
		return a > b;
	}
};

int main()
{
	int arr[6] = {1,3,5,8,6,4};
	vector<int> vi(arr, arr + 6);	
	/*
	* vector			模板
	* vector<int>		模板实例化    也就是 类
	* vector<int> vi	类生成对象
	* vector<int> vi(arr, arr + 6);		类生成对象的入参
	*/	

	//sort(vi.begin(),vi.end(), myCompare);	//排序	但是C++中这种方法不被看好
	
	//Compare c;
	//sort(vi.begin(),vi.end(), c);	//排序	(使用对象)
	
	sort(vi.begin(),vi.end(), Compare());	//排序	(回调仿函数实现)使用匿名对象
	
	vector<int>::iterator itr;		
	for (itr = vi.begin(); itr != vi.end(); ++itr)//C++98标准打印数组
	{
		cout << *itr << endl;
	}
	return 0;
}

运行结果为:
运行结果

functor 的优势

那么上面传递匿名对象有什么优势呢?
functor 的优势在于,是对象形式,可以携带更多的的信息,用于作出判断。

比如,我们可以在对象初始化的时候,传入参数来决定状态,而不用去修改原代码。

调用类对象可以传递参数,可以携带变量。
代码演示:

#include <iostream>
#include <math.h>
#include <algorithm>		//算法
#include <vector>			//STL-vector
using namespace std;


bool myCompare(int a, int b)
{
	return a > b;
}


class Compare
{
public:
	Compare(bool b = true)
		:flag(b)
	{}
	
	bool operator()(int a, int b)
	{
		if(flag == true)
		return a > b;	//按照从大到小的顺序排序
		else
		return a < b;	//按照从小到大的顺序排序
	}
private:
	bool flag;
};

int main()
{
	int arr[6] = {1,3,5,8,6,4};
	vector<int> vi(arr, arr + 6);	
	/*
	* vector			模板
	* vector<int>		模板实例化    也就是 类
	* vector<int> vi	类生成对象
	* vector<int> vi(arr, arr + 6);		类生成对象的入参
	*/	

	sort(vi.begin(),vi.end(), Compare(true));	//降序排列

	vector<int>::iterator itr;		
	for (itr = vi.begin(); itr != vi.end(); ++itr)//C++98标准打印数组
	{
		cout << *itr << endl;
	}

	sort(vi.begin(), vi.end(), Compare(false));	//升序排列

	cout << "==============================" << endl;

	for (itr = vi.begin(); itr != vi.end(); ++itr)
	{
		cout << *itr << endl;
	}
	
	return 0;
}

运行结果:
运行结果
对象像函数一样使用。

举报

相关推荐

0 条评论