本系列文章为黑马程序员C++教程学习笔记,前面的系列文章链接如下
C++核心编程:P1->程序的内存模型
C++核心编程:P2->引用
C++核心编程:P3->函数提高
C++核心编程:P4->类和对象----封装
C++核心编程:P5->类和对象----对象的初始化和清理
C++核心编程:P6->类和对象----C++对象模型和this指针
C++核心编程:P7->类和对象----友元
C++核心编程:P8->类和对象----运算符重载
C++核心编程:P9->类和对象----继承
C++核心编程:P10->类和对象----多态
C++核心编程:P11->文件操作
C++核心编程:P12->模板----函数模板
C++核心编程:P13->模板----类模板
C++核心编程:P14->STL----STL初识
C++核心编程:P15->STL----常用容器(上)
C++核心编程:P16->STL----常用容器(下)
- 一、函数对象
- 二、谓词
- 三、内建函数对象
- 3.1 算术仿函数
- 3.2 关系仿函数
- 3.3 逻辑仿函数
一、函数对象
函数对象概念
概念:
①重载函数调用操作符的类,其对象常称为函数对象。
②函数对象使用重载的()时,行为类似函数调用,也叫仿函数。
本质: 函数对象(仿函数)是一个类,不是一个函数。
函数对象使用
①函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值。
②函数对象超出普通函数的概念,函数对象可以有自己的状态。
③函数对象可以作为参数传递。
案例: 测试函数对象的几种使用方法
#include#include using namespace std; //1、函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值 class MyAdd { public: int operator()(int a, int b) { return a + b; } }; //2、函数对象可以有自己的状态 class MyPrint { public: MyPrint() { count = 0; } void operator()(string test) { cout << test << endl; count++; //统计调用次数 } //记录状态 int count; }; //3、函数对象可以作为参数传递 void doPrint(MyPrint& mp, string test) { mp(test); } void test01() { MyAdd myadd; cout << myadd(10, 10) << endl; MyPrint myprint; myprint("hello world"); myprint("hello world"); myprint("hello world"); myprint("hello world"); cout << "MyPrint调用次数为:" << myprint.count << endl; MyPrint mp; doPrint(mp, "Hello C++"); } int main() { test01(); system("pause"); return 0; }
运行,效果如下
二、谓词
谓词概念
①返回bool类型的仿函数称为谓词。
②如果operator()接受一个参数,那么叫做一元谓词。
③如果operator()接受两个参数,那么叫做二元谓词。
案例: 一元谓词
创建一个vector数组,push进去一些元素,使用find_if查找大于5的元素。首先我们看下find_if的定义
接着写出一元谓词
#include#include #include using namespace std; class GreaterFive { public: bool operator()(int val) { return val > 5; } }; void test01() { vector v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector ::iterator it = find_if(v.begin(), v.end(), GreaterFive()); if (it == v.end()) { cout << "没找到" << endl; } else { cout << "找到了,元素是:" << *it << endl; } } int main() { test01(); system("pause"); return 0; }
运行,效果如下。
案例: 二元谓词
创建一个vector数组,插入一些元素,然后指定从大到小的排列顺序。
#include#include #include using namespace std; class myCompare { public: bool operator()(int a, int b) { return a > b; } }; void test01() { vector v; v.push_back(10); v.push_back(30); v.push_back(20); v.push_back(40); v.push_back(50); for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; cout << "---------------------" << endl; sort(v.begin(), v.end(), myCompare()); for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
运行,效果如下
三、内建函数对象
概念: STL内建了一些函数对象
分类:
①算术仿函数
②关系仿函数
③逻辑仿函数
用法:
①这些仿函数所产生的对象,用法和一般函数完全相同
②使用内建函数对象,需要引入头文件 #include
3.1 算术仿函数
功能描述:
实现四则运算
其中negate是一元运算,其他都是二元运算
仿函数原型:
templateT plus //加法仿函数
templateT minus //减法仿函数
templateT multiplies //乘法仿函数
templateT divides //除法仿函数
templateT modulus //取模仿函数
templateT negate //取反仿函数
案例: 测试取反仿函数和加法仿函数
#include#include using namespace std; void test01() { negate n; cout << n(50) << endl; plus p; cout << p(10, 20) << endl; } int main() { test01(); system("pause"); return 0; }
运行,效果如下。
3.2 关系仿函数
功能描述: 实现关系对比
仿函数原型:
templatebool equal_to //等于
templatebool not_equal_to //不等于
templatebool greater //大于
templatebool greater_equal //大于等于
templatebool less //小于
templatebool less_equal //小于等于
案例: 创建一个vector数组,插入一些元素,使用仿函数greater对sort指定排序规则。
首先看看sort的源码,可以看出sort有2个重载版本,默认的版本指定了仿函数less。所以每次使用sort不指定仿函数时,结果按照从小到大排列。
指定仿函数greater
#include#include #include #include using namespace std; void test01() { vector v; v.push_back(10); v.push_back(40); v.push_back(20); v.push_back(30); v.push_back(50); for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; sort(v.begin(), v.end(), greater ()); for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
运行,效果如下。
3.3 逻辑仿函数
功能描述: 实现逻辑运算
函数原型:
templatebool logical_and //逻辑与
templatebool logical_or //逻辑或
templatebool logical_not //逻辑非
案例: 创建一个Vector数组,插入一些元素。创建另外一个vector数组,将原vector数组的元素搬移至新的vector中,并指定仿函数。
#include#include #include #include using namespace std; void test01() { vector v; v.push_back(true); v.push_back(false); v.push_back(true); v.push_back(false); v.push_back(true); for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; vector v2; v2.resize(v.size()); transform(v.begin(), v.end(), v2.begin(), logical_not ()); for (vector ::iterator it = v2.begin(); it != v2.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
运行,效果如下。



