C++ 学习之函数对象

news/2024/5/20 18:32:48/文章来源:https://blog.csdn.net/sixpp/article/details/136278728

在这里插入图片描述

C++ 函数对象基本概念

在C++中,函数对象(Function Objects)是一种类或结构体,它重载了函数调用运算符operator(),因此可以像函数一样被调用。函数对象有时也被称为仿函数(Functor)。

以下是关于C++函数对象的基本概念:

  1. 使用函数对象:函数对象可以像普通函数一样被调用,通过在对象后加括号并传递参数来执行操作。例如:

    #include <iostream>struct Add {int operator()(int a, int b) { return a + b; }
    };int main() {Add adder;std::cout << adder(3, 4) << std::endl;  // 调用函数对象return 0;
    }
    
  2. 重载operator():函数对象需要重载operator(),并根据需要定义参数和返回值。通过重载operator(),函数对象就可以像函数一样被调用。

  3. 状态保持:与普通函数不同的是,函数对象可以包含状态。这意味着函数对象可以在其内部保持一些状态信息,并在每次调用时进行更新。这使得函数对象更加灵活且功能强大。

  4. 模板函数对象:函数对象可以是模板类,可以接受不同类型的参数。这样可以实现更通用和灵活的函数对象,适用于多种情况。

  5. 标准库中的函数对象:C++标准库提供了许多预定义的函数对象,如std::plusstd::minusstd::greater等,可以直接使用这些函数对象完成特定的操作,而不用自己定义函数对象。

  6. 使用场景:函数对象通常用于泛型编程、STL算法、排序、自定义比较函数等情况。通过函数对象,我们可以定义自己的函数行为,并将其应用于各种数据结构和算法中。

通过函数对象,C++提供了一种更加灵活和可定制的函数调用方式,使编程变得更加方便和高效。

C++ 函数对象使用

在C++中,函数对象(Function Objects)可以通过类或结构体重载operator()来实现,从而使其像函数一样被调用。使用函数对象可以提供更灵活和通用的函数行为,适用于各种情况。以下是一些关于如何定义和使用函数对象的示例:
在这里插入图片描述

示例1:定义一个简单的函数对象并调用

#include <iostream>// 定义一个加法函数对象
struct Add {int operator()(int a, int b) {return a + b;}
};int main() {Add adder; // 创建函数对象int result = adder(3, 4); // 调用函数对象std::cout << "Result: " << result << std::endl;return 0;
}

示例2:利用函数对象实现自定义排序

#include <iostream>
#include <vector>
#include <algorithm>// 自定义升序排序函数对象
struct AscendingOrder {bool operator()(int a, int b) {return a < b;}
};int main() {std::vector<int> numbers = {5, 2, 8, 1, 4};// 使用函数对象进行升序排序AscendingOrder ascending_order;std::sort(numbers.begin(), numbers.end(), ascending_order);// 输出排序结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

示例3:利用标准库提供的函数对象

#include <iostream>
#include <algorithm>
#include <vector>int main() {std::vector<int> numbers = {5, 2, 8, 1, 4};// 使用标准库提供的函数对象std::greater进行降序排序std::sort(numbers.begin(), numbers.end(), std::greater<int>());// 输出排序结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

通过这些示例,您可以看到如何定义和使用函数对象来实现自定义操作、排序、比较等功能。函数对象在STL算法、泛型编程、模板编程等方面有着广泛的应用,能够使代码更通用、可复用和高效。

C++ 一元谓词

在这里插入图片描述

在C++中,一元谓词(Unary Predicate)是一个函数对象或函数指针,它接受一个参数并返回一个bool值。一元谓词通常用于标准库算法中,作为条件判断或过滤的依据。一元谓词的主要特点是只接受一个参数。

下面是一个简单的示例来说明一元谓词的用法:

#include <iostream>
#include <vector>
#include <algorithm>// 一元谓词函数对象,用于判断一个整数是否为偶数
struct IsEven {bool operator()(int n) {return n % 2 == 0;}
};int main() {std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};// 使用一元谓词IsEven进行筛选,只保留偶数auto it = std::remove_if(numbers.begin(), numbers.end(), IsEven());// 调用erase方法擦除不符合条件的元素numbers.erase(it, numbers.end());// 输出结果for(int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们定义了一个一元谓词函数对象IsEven,它判断一个整数是否为偶数。然后我们使用std::remove_if算法结合该一元谓词对容器numbers进行筛选,去除所有不满足条件的元素,最后输出剩余的偶数。

一元谓词在很多情况下都非常有用,可以帮助我们根据自定义的条件来进行数据筛选、操作等。通过使用一元谓词,您可以更灵活地控制算法的行为,并适应各种需求。

C++ 二元谓词

在C++中,二元谓词(Binary Predicate)是一个函数对象或函数指针,它接受两个参数并返回一个bool值。二元谓词通常在标准库算法中使用,用于比较两个元素或判断它们之间的关系。

下面是一个简单的示例来说明二元谓词的用法:

#include <iostream>
#include <vector>
#include <algorithm>// 二元谓词函数对象,用于比较两个整数的大小关系
struct Compare {bool operator()(int a, int b) {return a < b;}
};int main() {std::vector<int> numbers = {4, 2, 7, 3, 9, 5};// 使用二元谓词Compare进行排序std::sort(numbers.begin(), numbers.end(), Compare());// 输出排序结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们定义了一个二元谓词函数对象Compare,它比较两个整数的大小关系。然后我们使用std::sort算法结合该二元谓词对容器numbers进行排序,按照自定义的比较函数对象来重新排列元素顺序。

二元谓词在排序、查找、删除等需要考虑元素之间关系的情况下非常有用。通过提供自定义的二元谓词,我们可以灵活地控制算法的行为,满足各种不同的需求。

C++ 函数对象算数仿函数

函数对象(Function Objects)在C++中也可以作为算术仿函数(Arithmetic Functors)使用,它们模拟了基本的算术操作符(如加法、减法、乘法和除法),使其能够像函数一样被调用。

以下是一些示例说明如何使用函数对象作为算术仿函数:

示例1:使用函数对象实现加法仿函数

#include <iostream>// 定义一个加法仿函数
struct Add {int operator()(int a, int b) const {return a + b;}
};int main() {Add adder; // 创建加法仿函数对象int result = adder(3, 4); // 调用加法仿函数std::cout << "Result: " << result << std::endl;return 0;
}

示例2:使用函数对象实现乘法仿函数

#include <iostream>// 定义一个乘法仿函数
struct Multiply {int operator()(int a, int b) const {return a * b;}
};int main() {Multiply multiplier; // 创建乘法仿函数对象int result = multiplier(3, 4); // 调用乘法仿函数std::cout << "Result: " << result << std::endl;return 0;
}

示例3:使用标准库提供的算术仿函数

#include <iostream>
#include <functional>int main() {std::plus<int> adder; // 创建加法仿函数对象int result = adder(3, 4); // 调用加法仿函数std::cout << "Result: " << result << std::endl;std::multiplies<int> multiplier; // 创建乘法仿函数对象result = multiplier(3, 4); // 调用乘法仿函数std::cout << "Result: " << result << std::endl;return 0;
}

通过这些示例,您可以看到如何使用函数对象作为算术仿函数,从而进行加法和乘法运算。您可以自定义函数对象来实现更复杂的算术操作,或者使用标准库提供的算术仿函数(如std::plusstd::multiplies)来简化代码。

C++ 函数对象关系仿函数

函数对象关系仿函数(Function Object Relational Functors)用于比较两个对象之间的关系,例如相等、不相等、大于、小于等。它们通常被用于需要排序、查找或筛选操作中。

以下是一些示例说明如何使用函数对象关系仿函数:

示例1:使用函数对象关系仿函数进行相等判断

#include <iostream>
#include <functional>int main() {std::equal_to<int> isEqual; // 创建相等仿函数对象bool result = isEqual(3, 4); // 判断两个数是否相等std::cout << "Is equal: " << std::boolalpha << result << std::endl;return 0;
}

示例2:使用函数对象关系仿函数进行大小比较

#include <iostream>
#include <functional>int main() {std::greater<int> isGreater; // 创建大于仿函数对象bool result = isGreater(3, 4); // 判断第一个数是否大于第二个数std::cout << "Is greater: " << std::boolalpha << result << std::endl;std::less<int> isLess; // 创建小于仿函数对象result = isLess(3, 4); // 判断第一个数是否小于第二个数std::cout << "Is less: " << std::boolalpha << result << std::endl;return 0;
}

示例3:自定义函数对象关系仿函数进行字符串长度比较

#include <iostream>
#include <string>// 自定义字符串长度比较仿函数
struct StringLengthComparator {bool operator()(const std::string& str1, const std::string& str2) const {return str1.length() < str2.length();}
};int main() {StringLengthComparator compareLength; // 创建字符串长度比较仿函数对象bool result = compareLength("apple", "banana"); // 判断第一个字符串的长度是否小于第二个字符串的长度std::cout << "Is length less: " << std::boolalpha << result << std::endl;return 0;
}

通过这些示例,您可以看到如何使用函数对象关系仿函数来进行对象之间的关系判断。您可以使用标准库提供的函数对象关系仿函数(如std::equal_tostd::greaterstd::less),也可以自定义函数对象关系仿函数来满足特定需求。

C++ 函数对象逻辑仿函数

函数对象逻辑仿函数(Function Object Logical Functors)用于执行逻辑运算,比如逻辑与、逻辑或、逻辑非等操作。它们通常被用于需要对多个条件进行组合判断的情况。

以下是一些示例说明如何使用函数对象逻辑仿函数:

示例1:使用函数对象逻辑仿函数进行逻辑与操作

#include <iostream>
#include <functional>int main() {std::logical_and<bool> andOp; // 创建逻辑与仿函数对象bool result = andOp(true, false); // 判断两个条件是否同时为真std::cout << "Logical AND result: " << std::boolalpha << result << std::endl;return 0;
}

示例2:使用函数对象逻辑仿函数进行逻辑或操作

#include <iostream>
#include <functional>int main() {std::logical_or<bool> orOp; // 创建逻辑或仿函数对象bool result = orOp(true, false); // 判断两个条件是否至少有一个为真std::cout << "Logical OR result: " << std::boolalpha << result << std::endl;return 0;
}

示例3:自定义函数对象逻辑仿函数进行逻辑非操作

#include <iostream>// 自定义逻辑非仿函数
struct LogicalNot {bool operator()(bool value) const {return !value;}
};int main() {LogicalNot notOp; // 创建逻辑非仿函数对象bool result = notOp(true); // 对给定条件取逻辑非std::cout << "Logical NOT result: " << std::boolalpha << result << std::endl;return 0;
}

通过这些示例,您可以看到如何使用函数对象逻辑仿函数来执行逻辑运算。您可以使用标准库提供的逻辑仿函数(如std::logical_andstd::logical_or),也可以自定义函数对象逻辑仿函数来实现特定的逻辑操作。

关注我,不迷路,共学习,同进步

在这里插入图片描述

关注我,不迷路,共学习,同进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_982771.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ONLYOFFICE 8.0版本深度测评:革新之作还是失望之作?

引言 &#xff1a; 随着办公自动化需求的不断升级&#xff0c;拥有一款功能全面、操作便捷的办公软件显得尤为重要。在这个背景下&#xff0c;ONLYOFFICE作为一款集文档编辑、表格处理、演示制作等多功能于一体的办公套件&#xff0c;吸引了众多用户的关注。近期&#xff0c;O…

进程间通信:共享内存与信号灯集(2024/2/26)

作业1&#xff1a;共享内存 shmsnd.c: #include <myhead.h> #define PAGE_SIZE 4096int main(int argc, const char *argv[]) {//一、创建key值key_t key-1;if((keyftok("/",k))-1){perror("ftok error");return -1;}//二、根据key值创建共享内存i…

HTML+CSS+JS:花瓣登录组件

效果演示 实现了一个具有动态花朵背景和简洁登录框的登录页面效果。 Code <section><img src"./img/background.jpeg" class"background"><div class"login"><h2>Sign In</h2><div class"inputBox"…

学习磁盘管理

文章目录 一、磁盘接口类型二、磁盘设备的命名三、fdisk分区四、自动挂载五、扩容swap六、GPT分区七、逻辑卷管理八、磁盘配额九、RAID十、软硬链接 一、磁盘接口类型 IDE、SATA、SCSI、SAS、FC&#xff08;光纤通道&#xff09; IDE, 该接口是并口。SATA, 该接口是串口。SCS…

如何使用自动化工具编写测试用例?

以下为作者观点&#xff0c;仅供参考&#xff1a; 在快速变化的软件开发领域&#xff0c;保证应用程序的可靠性和质量至关重要。随着应用程序复杂性和规模的不断增加&#xff0c;仅手动测试无法满足行业需求。 这就是测试自动化发挥作用的地方&#xff0c;它使软件测试人员能…

用Python实现创建餐厅评分数据分析表

代码的功能是创建一个雷达图&#xff08;Radar Chart&#xff09;&#xff0c;也称为蜘蛛网图&#xff08;Spider Chart&#xff09;&#xff0c;用来展示不同餐厅在多个维度上的评分。雷达图是一种非常适合展示多维数据的图形&#xff0c;它能够清楚地显示每个数据点在多个变量…

抖音视频评论数据提取软件|抖音数据抓取工具

一、开发背景&#xff1a; 在业务需求中&#xff0c;我们经常需要下载抖音视频。然而&#xff0c;在网上找到的视频通常只能通过逐个复制链接的方式进行抓取和下载&#xff0c;这种操作非常耗时。我们希望能够通过关键词自动批量抓取并选择性地下载抖音视频。因此&#xff0c;为…

【JVM】线上一次fullGC排查思路

fullGC问题背景 监控告警发现&#xff0c;今天开始我们线上应用频繁出现fullGC&#xff0c;并且每次出现后磁盘都会被占满 查看监控 查看监控发现FULLGC的机器均为同一个机房的集器&#xff0c;并且该机房有线上error报错&#xff0c;数据库监控对应的时间点也有异常&#x…

将一个 PostgreSQL 数据库复制到另一个数据库中

以管理员身份进入cmd窗口&#xff0c;输入如下命令 语法&#xff1a; pg_dump -C -h 本机IP -U 本机postgresql用户名 源数据库名 | psql -h 服务器IP -U 服务器postgresql用户名 目标数据库名 示例&#xff1a; pg_dump -C -h 127.0.0.1 -U postgres test01-dbname | psql…

02|Explain详解

1. Explain工具介绍 Explain关键字可以模拟优化器执行SQL语句&#xff0c;析查询语句或结构的性能瓶颈位置使用方式&#xff1a; explain 关键字 select语句 MySQL 会在査询上设置一个标记&#xff0c;执行査询会返问执行计划的信息&#xff0c;而不是执行这条SQL。 注意:如果…

设计模式六:策略模式

1、策略模式 策略模式定义了一系列的算法&#xff0c;并将每一个算法封装起来&#xff0c;使每个算法可以相互替代&#xff0c;使算法本身和使用算法的客户端分割开来&#xff0c;相互独立。 策略模式的角色&#xff1a; 策略接口角色IStrategy&#xff1a;用来约束一系列具体…

Javaweb之SpringBootWeb案例之切入点表达式的详细解析

3.3 切入点表达式 从AOP的入门程序到现在&#xff0c;我们一直都在使用切入点表达式来描述切入点。下面我们就来详细的介绍一下切入点表达式的具体写法。 切入点表达式&#xff1a; 描述切入点方法的一种表达式 作用&#xff1a;主要用来决定项目中的哪些方法需要加入通知 …

备战蓝桥杯————递归反转单链表

当要求只反转单链表中的一部分时&#xff0c;递归实现确实具有一定的挑战性&#xff0c;但也是可行的。下面我将介绍一种递归实现的方法来反转单链表中的一部分。 一、反转链表 题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示…

qt-C++笔记之事件过滤器

qt-C笔记之事件过滤器 —— 杭州 2024-02-25 code review! 文章目录 qt-C笔记之事件过滤器一.使用事件过滤器和不使用事件过滤器对比1.1.使用事件过滤器1.2.不使用事件过滤器1.3.比较 二.Qt 中事件过滤器存在的意义三.为什么要重写QObject的eventFilter方法&#xff1f;使用QO…

SpringCloud Nacos安装

1. Nacos的下载&#xff1a;下载的是1.4的版本。 2. Nacos的安装&#xff1a; startup.cmd -m standalone 以单机模式启动Nacos。 登录的账号密码 都是nacos。

Spring Session:Redis序列化配置|Session事件监听

Spring Session是可配置的。 Redis Configuration JSON序列化配置 Spring Session默认使用Java对象序列化机制对Session属性值进行序列化。 预定义类SysUser 先来定义一个SysUser类&#xff0c;在下面的演示案例中会用到。 package com.example.demo.model.entity;import j…

【问题解决】Python matplotlib 画图显示中文字符

import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号

01|Mysql底层存储引擎

1. 聚集索引&#xff08;聚簇&#xff09;与非聚集索引 1.1 聚集索引 索引和数据存储在一起。叶子节点存储了完整的数据记录&#xff1b; 1.2 非聚集索引 MyISAM存储引擎就是非聚集索引&#xff0c;索引和数据文件是分开存储的。索引在MYI文件中&#xff0c;数据在MYD文件中…

数据库期末简答题速成-救命专用

简答题&#xff1a; 第 1 章 绪论 DBMS 的主要功能有哪些&#xff1f; 答&#xff1a;数据库管理系统&#xff08;DBMS&#xff09;是位于操作系统与用户之间的一个数据管理软件&#xff0c;它主要功能包括以下几个方面&#xff1a; 数据定义功能 DBMS提供数据描述语言&…