函数对象与适配器

函数对象

重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor)其实就是重载"()"操作符,使得类对象可以像函数那样调用。

注意
1.函数对象(仿函数是一个类,不是一个函数)。
2.函数对象(仿函数)重载了"()"操作符使得它可以像函数一样调用。。
分类假定某个类有一个重载的 operator(),而且重载的 operator()要求获取一个参数,我们就将这个类称为"一元仿函数(unary functor);相反,如果重载的 operator()要求获取两个参数,就将这个类称为 二元仿函数(binary functor )。

函数对象的作用主要是什么?STL 提供的算法往往都有两个版本,其中一个版本表现出最常用的某种运算 另一版本则允许用户通过template参数的形式来指定所要采取的策略。

总结
1.函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会发生任何问题,避免了函数调用的运行时问题。·
2、函数对象超出普通函数的概念,函数对象可以有自己的状态。
3、函数对象可内联编译,性能好。用函数指针几乎不可能, 
4、模板函数对象使函数对象具有通用性,这也是它的优势之一
#include <iostream>
#include <algorithm>

using namespace std;

//仿函数
class Person
{
public:
    void operator()(int num)
    {
        cout << num << endl;
    }
};
void test()
{
	//person是一个类
    Person sss;
    sss(222);  //仿函数的调用
    Person()(3333);//使用了匿名对象
}

int main()
{
    test();

}

函数对象已经超出了普通函数的概念  内部可以保存状态
函数对象可以作为参数传递
#include <iostream>
#include <algorithm>

using namespace std;

//仿函数
class Person
{
public:
    void operator()(int num)
    {
        cout << num << endl;
        count++;
    }
    int count = 0;
};

//函数对象不同于普通函数   可以记录次数
void test01()
{
    Person sss;
    sss(111); 
    sss(222);
    sss(333);
    sss(444);
    cout << "调用次数" << sss.count << endl;

}
//函数对象作为值传递
void test02(Person sss, int num)
{
    sss(num);
}

int main()
{
    test01();
    
    test02(Person(),555); //通过匿名对象

}

谓词

普通函数或函数对象重载() 返回值为bool	

在这里插入图片描述

适配器

函数的是适配器
1.包含头文件   functional
2.绑定数据  bind2nd(绑定的为第二个参数  )   这是仿函数需要俩个数据   仿函数一个数据无需绑定
3.仿函数需要继承binary_function<参数1,参数2,返回值类型>
4.仿函数需要加const修饰operater()
5.bind1st绑定的为仿函数中的第一个参数
#include "iostream"
#include "functional"
#include <vector>
#include <algorithm>

using namespace std;

void peint(int aa)
{
	cout << aa << endl;
}

class peint02:public binary_function<int,int,void>
{
public:
	void operator()(int aa, int num)const
	{
		cout << aa + num << endl;
	}
};
void  test()
{
	vector<int> a;
	a.push_back(10);
	a.push_back(20);
	a.push_back(30);
	a.push_back(40);
	int num;
	cin >> num;
	for_each(a.begin(), a.end(), peint);//注意括号<>里面填写仿函数不需要括号  
	for_each(a.begin(), a.end(), bind2nd(peint02(),num));//而在函数调用的()里  普通函数变为回调函数 仿函数救赎隐式调用


}

int  main()
{
	test();
}

在这里插入图片描述

取反是适配器
1.一元取反适配器  not1
2.继承unary_function<参数类型1,返回值>
3.const修饰operator()
4.二元取反适配器  not2
#include "iostream"
#include "functional"
#include <vector>
#include <algorithm>

using namespace std;

class Less :public unary_function<int, bool>
{
public:
	bool operator()(int num)const
	{
		return num > 5;
	}
};


void  test()
{
	vector<int> a;
	for (int i = 0;i < 10;i++)
	{
		a.push_back(i);
	}
	//找出大于5的数
	vector<int>::iterator v = find_if(a.begin(), a.end(), bind2nd(greater<int>(), 5));
	if (v != a.end())
	{
		cout << *v << endl;
	}
	//找出小于5的数
	//vector<int>::iterator s = find_if(a.begin(), a.end(), not1(bind2nd(greater<int>(), 5)));  //利用内建函数
	vector<int>::iterator s = find_if(a.begin(), a.end(), not1(Less())); //利用仿函数
	if (s != a.end())
	{
		cout << *s << endl;
	}
}

int  main()
{
	test();
}
函数指针适配器
1.将函数指针适配为函数对象

void add(int num, int start)
{
	cout << num + start << endl;
}


void  test()
{
	vector<int>a;
	for (int i = 0;i < 10;i++)
	{
		a.push_back(i);
	}
	//函数指针适配器
	//ptr_fun
	for_each(a.begin(), a.end(), bind2nd(ptr_fun(add), 100));
}

int  main()
{
	test();
}
成员函数适配器
#include "iostream"
#include "functional"
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

class Person
{	
public:
	Person(string name, int age)
	{
		my_age = age;
		my_name = name;
	}
	void display() const
	{
		cout << "名字" << my_name << " " << "年龄" << my_age << endl;
	}
private:
	string my_name;
	int my_age;
};

void  test()
{
	vector<Person>a;
	Person p1("aaa", 15);
	Person p2("sss", 24);
	Person p3("axxxaa", 54);
	Person p4("hgf", 45);


	a.push_back(p1);
	a.push_back(p2);
	a.push_back(p3);
	a.push_back(p4);

	//利用类成员模板
	//mem_fun_ref
	for_each(a.begin(), a.end(), mem_fun_ref(&Person::display));

}

int  main()
{
	test();
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值