Java 转 C++ 系列:函数对象、谓词和内建函数对象

文章参考:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难


文章目录

  • 一、函数对象
    • [1.1 函数对象概念](#1.1 函数对象概念)
    • [1.2 函数对象使用](#1.2 函数对象使用)
  • 二、谓词
    • [2.1 谓词概念](#2.1 谓词概念)
    • [2.2 一元谓词](#2.2 一元谓词)
    • [2.3 二元谓词](#2.3 二元谓词)
  • 三、内建函数对象
    • [3.1 内建函数对象意义](#3.1 内建函数对象意义)
    • [3.2 算术仿函数](#3.2 算术仿函数)
    • [3.3 关系仿函数](#3.3 关系仿函数)
    • [3.4 逻辑仿函数](#3.4 逻辑仿函数)

一、函数对象

1.1 函数对象概念

概念: 一个类如果重载了 operator(),这个类实例化出来的对象,就叫作: 函数对象 。函数对象使用重载的()时,行为类似函数调用,因此也常叫 仿函数
本质: 函数对象(仿函数)是一个,不是一个函数。


1.2 函数对象使用

  • 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
  • 函数对象可以有自己的状态
  • 函数对象可以作为参数传递

示例代码:

cpp 复制代码
#include<iostream>
#include<string>
using namespace std;

class MyAdd {
public:
	// 重载()
	int operator()(int v1, int v2) {
		return v1 + v2;
	}
};

class MyPrint {
public:
	MyPrint() {
		this->count = 0;
	}
	// 重载()
	void operator()(string test) {
		cout << test << endl;
		this->count++;
	}
	int count; // 内部自己的状态
};

void doPrint(MyPrint& mp, string test) {
	mp(test);
}

int main() {
	system("chcp 65001> nul");

	//1、函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
	MyAdd myAdd;
	cout << myAdd(10, 10) << endl; // 函数对象使用重载的()时,行为类似函数调用

	//2、函数对象可以有自己的状态
	MyPrint myPrint;
	myPrint("hello C++");
	myPrint("hello C++");
	myPrint("hello C++");
	cout << myPrint.count << endl;

	//3、函数对象可以作为参数传递
	MyPrint myPrint2;
	doPrint(myPrint2, "hello world");

	system("pause");
	return 0;
}

二、谓词

2.1 谓词概念

概念:

  • 返回 bool 类型的仿函数称为谓词
  • 如果 operator() 接受一个参数,那么叫做一元谓词
  • 如果 operator() 接受两个参数,那么叫做二元谓词

2.2 一元谓词

案例:查找容器中大于5的数字

cpp 复制代码
#include<iostream>
#include<string>
#include<vector>
using namespace std;

class GreaterFive {
public:
	bool operator()(int val) {
		return val > 5;
	}
};

int main() {
	system("chcp 65001> nul");

	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}

	// 查找容器中大于5的数字
	vector<int>::iterator ite = find_if(v.begin(), v.end(), GreaterFive()); //GreaterFive()是匿名对象
	if (ite == v.end()) {
		cout << "未找到" << endl;
	}
	else {
		cout << "找到了" << endl;
		cout << *ite << endl;// 6
	}

	system("pause");
	return 0;
}

2.3 二元谓词

案例:使用函数对象,改变算法策略

cpp 复制代码
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

void printVector(const vector<int>& v) {
	for (vector<int>::const_iterator  it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

class MyCompare {
public:
	bool operator()(int val1, int val2) {
		return val1 > val2;
	}
};

int main() {
	system("chcp 65001> nul");

	vector<int> v = { 10, 40, 20, 30, 50 };
	sort(v.begin(), v.end());
	printVector(v); // 10 20 30 40 50
	
	// 使用函数对象,改变算法策略
	sort(v.begin(), v.end(), MyCompare());
	printVector(v); // 50 40 30 20 10

	system("pause");
	return 0;
}

三、内建函数对象

3.1 内建函数对象意义

概念: STL内建了一些函数对象

分类: 算术仿函数、关系仿函数、逻辑仿函数

用法:

  • 这些仿函数所产生的对象,用法和一般函数完全相同
  • 使用内建函数对象,需要引入头文件 #include<functional>

3.2 算术仿函数

功能描述: 实现四则运算,其中 negate 是一元运算,其他都是二元运算

cpp 复制代码
// 算术仿函数(内置,需包含头文件 <functional>)
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>        , 取反仿函数

代码示例:

cpp 复制代码
#include<iostream>
#include<string>
#include<functional>
using namespace std;

int main() {
	system("chcp 65001> nul");

	// negate 一元仿函数
	negate<int> n;`在这里插入代码片`
	cout << n(50) << endl; // -50 取反仿函数

	// plus 二元仿函数
	plus<int> p;
	cout << p(10, 20) << endl; // 30 加法仿函数

	system("pause");
	return 0;
}

3.3 关系仿函数

功能描述: 实现关系对比

cpp 复制代码
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>           , 小于等于
cpp 复制代码
#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;

void printVector(const vector<int>& v) {
	for (const auto& val : v) {
		cout << val << " ";
	}
	cout << endl;
}

int main() {
	system("chcp 65001> nul");
	vector<int> v = { 10, 30, 20, 50, 40 };
	printVector(v); // 10 20 30 40 50

	// 大于 greater
	sort(v.begin(), v.end(), greater<int>());
	printVector(v); // 50 40 30 20 10

	system("pause");
	return 0;
}

3.4 逻辑仿函数

功能描述: 实现逻辑运算

cpp 复制代码
template<class T> bool logical_and<T>              , 逻辑与
template<class T> bool logical_or<T>               , 逻辑或
template<class T> bool logical_not<T>              , 逻辑非

示例代码:

cpp 复制代码
#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;

void printVector(const vector<bool>& v) {
	for (const auto& val : v) {
		cout << val << " ";
	}
	cout << endl;
}

int main() {
	system("chcp 65001> nul");
	vector<bool> v;
	v.push_back(true);
	v.push_back(false);
	printVector(v); // 1 0

	//逻辑非  将v容器搬运到v2中,并执行逻辑非运算
	vector<bool> v2;
	v2.resize(v.size());
	transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
	printVector(v2); // 0 1

	system("pause");
	return 0;
}
相关推荐
Full Stack Developme2 小时前
Hutool StrUtil 教程
开发语言·网络·python
代码羊羊2 小时前
Rust方法速览:从self到impl
开发语言·后端·rust
炘爚2 小时前
C++实现分布式集群聊天服务器
服务器·c++·分布式
低频电磁之道2 小时前
C++中 explicit 用法:多参数构造函数
c++
那个失眠的夜2 小时前
Spring整合Mybatis实现用户的CRUD
java·spring·mybatis
他是龙5512 小时前
63:JS 加密断点调试与逆向实战
开发语言·javascript·状态模式
superantwmhsxx2 小时前
Spring Initializr创建springboot项目,提示java 错误 无效的源发行版:16
java·spring boot·spring
山河梧念2 小时前
【保姆级教程】VMware虚拟机安装全流程
android·java·数据库
常利兵2 小时前
Kotlin类型魔法:Any、Unit、Nothing 深度探秘
android·开发语言·kotlin