1.函数对象:
概述:重载函数调用操作符的类,其对象常称为函数对象
(function object),即它们是 行为类似函数的对象,也叫仿函数(functor)
,其实就是重载“()”
操作符,使得类对象 可以像函数那样调用。
1.1注意:
.函数对象(仿函数)
是一个类,不是一个函数。
函 数对象(仿函数)重载了”() ”
操作符使得它可以像函数一样调用。
1.2分类:
假定某个类 有一个重载的 operator(),而且重载的 operator()要求获取一个参数,我们就将这 个类称为“一元仿函数
”(unary functor);相反,如果重载的 operator()要求获取 两个参数,就将这个类称为“二元仿函数
”(binary functor)。
1.3函数对象和遍历算法结合实例
class Print
{
public:
/*重载()操作符*/
int operator()(int a)
{
cout << a;
}
};
void test()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
/*使用函数对象*/
for_each(v.begin(), v.end(), Print());
}
1.4函数对象和排序算法结合实例
class Compare {
public:
bool operator()(int a, int b)
{
return a > b;
}
};
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
/*使用函数对象*/
sort(v.begin(), v.end(), Compare());
}
注:除了和一些算法配合使用之外,还可以作为参数传参。
1.5小结:
1>、函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会 发生任何问题,避免了函数调用的运行时问题。
2>、函数对象超出普通函数的概 念,函数对象可以有自己的状态
3>、函数对象可内联编译,性能好。用函数指针 几乎不可能
4>、模版函数对象使函数对象具有通用性,这也是它的优势之
2.谓词
2.1概述:
谓词是指普通函数或重载的 operator()返回值是 bool 类型的函数对象(仿函数)。如 果 operator 接受一个参数,那么叫做一元谓词,如果接受两个参数,那么叫做二元 谓词,谓词可作为一个判断式。
2.2代码举例:
/*重载括号的二元谓词*/
class Compare {
public:
bool operator()(int a, int b)
{
return a > b;
}
};
/*普通函数的二元谓词*/
bool compare(int a, int b)
{
return a > b;
}
注:几个参数就是几元谓词,只要是返回值为bool类型的普通函数和重载()都可以叫做谓词。
3.内建函数对象
3.1概述:
STL 内建了一些函数对象。分为:算数类函数对象
,关系运算类函数对象
,逻辑运算 类仿函数
。这些仿函数所产生的对象,用法和一般函数完全相同,当然我们还可以 产生无名的临时对象来履行函数功能。
注:使用内建函数对象,需要引入头文件 #include <functional>
。
3.2,个算数类函数对象
template<class T> T plus<T>//加法仿函数
template<class T> T minus<T>//减法仿函数
template<class T> T multiplies<T>//乘法仿函数
template<class T> T divides<T>//除法仿函数
template<class T> T modulus<T>//取模仿函数
template<class T> T negate<T>//取反仿函数
注:除了 negate 是一元运算,其他都是二元运算
3.3关系运算类函数对象
template<class T> bool equal_to<T>//等于
template<class T> bool not_equal_to<T>//不等于
template<class T> bool greater<T>//大于
template<class T> bool greater_equal<T>//大于等于
template<class T> bool less<T>//小于
template<class T> bool less_equal<T>//小于等于
注:6 个关系运算类函数对象,每一种都是二元运算。
3.4逻辑运算类运算函数
template<class T> bool logical_and<T>//逻辑与
template<class T> bool logical_or<T>//逻辑或
template<class T> bool logical_not<T>//逻辑非
注:not 为一元运算,其余为二元运算
3.5取反函数简单举例
/*定义对象*/
negate<int> n;
/*使用普通对象做运算*/
cout << n(9);
/*使用匿名对象做运算*/
cout << negate<int>()(6) << endl;
4,适配器
概述:适配器就是用来适配参数,经常和仿函数一起使用。
4.1函数适配器
/*一元继承 public unary_funtion<参数类型, 返回值类型>
二元继承binary_function<参数类型, 参数类型, 返回值类型>
*/
class Print:public binary_function<int, int, void>
{
public:
void operator()(int a, int num)const
{
cout << a + num << endl;
}
};
void test02()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
/*/bind1st bind2nd 将二元函数对象转为一元函数对象*/
//for_each(v.begin(), v.end(), bind2nd(Print(), 10));
/*10传给a 对换位置*/
for_each(v.begin(), v.end(), bind1st(Print(), 10));
}
注:上述代码实现了将二元函数对象转为一元函数对象,总共有三步:
第一步:绑定
第二部:继承
第三步:加const
除了函数对象适配器还有取反适配器
,函数指针适配器 ptr_fun
,成员函数适配器
。
5.STL中的算法简述:
5.1for_each 遍历算法
遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象 *
for_each(iterator beg, iterator end, _callback);
5.2 transform 算法
transform 算法 将指定容器区间元素搬运到另一容器中
注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器
transform(iterator beg1, iterator end1, iterator beg2, _callbakc);
5.3常用的查找算法
5.3.1find 算法 查找元素
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置 */
find(iterator beg, iterator end, value)
5.3.2find_if 算法 条件查找
/*@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回 bool 类型的函数对象)
@return bool 查找返回 true 否则 false */
find_if(iterator beg, iterator end, _callback);
5.3.3adjacent_find 算法 查找相邻重复元素
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调函数或者谓词(返回 bool 类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器 */
adjacent_find(iterator beg, iterator end, _callback);
5.3.4 binary_search 算法 二分查找法
注意: 在无序序列中不可用
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return bool 查找返回 true 否则 false */
bool binary_search(iterator beg, iterator end, value);
5.3.5count 算法 统计元素出现次数
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 回调函数或者谓词(返回 bool 类型的函数对象)
@return int 返回元素个数 */
count(iterator beg, iterator end, value);
5.3.6count_if 算法 统计元素出现次数
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回 bool 类型的函数对象)
@return int 返回元素个数 */
count_if(iterator beg, iterator end, _callback);
5.4常用排序算法
5.4.1
/* merge 算法 容器元素合并,并存储到另一容器中 注意:两个容器必须是有序的 @param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器 */
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterat or dest)
/* sort 算法 容器元素排序
@param beg 容器 1 开始迭代器
@param end 容器 1 结束迭代器
@param _callback 回调函数或者谓词(返回 bool 类型的函数对象) */
sort(iterator beg, iterator end, _callback)
/* random_shuffle 算法 对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器 */
random_shuffle(iterator beg, iterator end)
/* reverse 算法 反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器 */
reverse(iterator beg, iterator end)
5.5 常用拷贝和替换算法
/* copy 算法 将容器内指定范围的元素拷贝到另一容器中
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标起始迭代器 */
copy(iterator beg, iterator end, iterator dest)
/* replace 算法 将容器内指定范围的旧元素修改为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param oldvalue 旧元素
@param oldvalue 新元素 */
replace(iterator beg, iterator end, oldvalue, newvalue)
/* replace_if 算法 将容器内指定范围满足条件的元素替换为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 函数回调或者谓词(返回 Bool 类型的函数对象)
@param oldvalue 新元素 */
replace_if(iterator beg, iterator end, _callback, newvalue)
/* swap 算法 互换两个容器的元素
@param c1 容器 1
@param c2 容器 2 */
swap(container c1, container c2)
5.6常用算数生成算法
/* accumulate 算法 计算容器元素累计总和
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 累加值 */
accumulate(iterator beg, iterator end, value)
/* fill 算法 向容器中添加元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t 填充元素 */
fill(iterator beg, iterator end, value)
5.7 常用集合算法
/* set_intersection 算法 求两个 set 集合的交集 注意:两个集合必须是有序序列
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址 */
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator e nd2, iterator dest)
/* set_union 算法 求两个 set 集合的并集 注意:两个集合必须是有序序列
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址 */
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, it erator dest)
/* set_difference 算法 求两个 set 集合的差集 注意:两个集合必须是有序序列
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址 */
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end 2, iterator dest)