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;
}
相关推荐
不会C语言的男孩16 分钟前
C++ Primer 第3章:字符串、向量和数组
开发语言·c++
兰令水18 分钟前
leecodecode【反前后指针】【2026.5.31打卡-java版本】
java·开发语言
Dovis(誓平步青云)1 小时前
《QT学习第四篇:常见事件与UDP、TCP、文件系统、(锁、信号量、条件变量》
c语言·开发语言·汇编·qt
code monkey.1 小时前
【Linux之旅】Linux 应用层自定义协议与序列化:从粘包问题到网络计算器
linux·网络·c++
草莓熊Lotso1 小时前
【Linux网络】深入理解 HTTP 协议(二):从协议格式到手写工业级 HTTP 服务器
linux·运维·服务器·网络·c++·http
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题 第87题】【Mysql篇】第17题:分布式事务的实现原理?
java·数据库·分布式·mysql·面试
来杯@Java9 小时前
图书管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·mybatis·课程设计
卷毛的技术笔记10 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥10 小时前
匿名函数 lambda + 高阶函数
java·python·算法
isyangli_blog10 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php