【STL十五】函数对象:可调用对象

【STL十五】函数对象:可调用对象

  • 一、可调用对象
    • 1、定义
    • 2、分类
  • 二、普通函数
    • 1、直接调用普通函数
    • 2、函数指针、函数引用
  • 三、仿函数——函数对象
  • 四、lambda表达式
  • 五、类的静态成员函数——(作为可调用对象,没有实用价值)
  • 六、类的非静态成员函数——(作为可调用对象,没有实用价值)
  • 七、可被转换为函数的类的对象——(作为可调用对象,没有实用价值)

  • 简介
    1、可调用对象这个概念在哔哩哔哩的一个视频中看到的概念。
    2、可调用对象:平时大家会用到的就三个:普通函数、仿函数、lambda表达式。
    3、本篇文章的重点在函数指针、函数引用;其它另外三种没有实用价值。

一、可调用对象

1、定义

  • 可调用对象:可以像函数一样调用的对象。
  • 可调用对象有类型,可以用指针存储它们的地址,可以被引用(类的成员函数除外)

2、分类

  • 普通函数
  • 仿函数
  • lambda函数
  • 类的静态成员函数——(作为可调用对象,没有实用价值)
  • 类的非静态成员函数——(作为可调用对象,没有实用价值)
  • 可被转换为函数的类的对象——(作为可调用对象,没有实用价值)

二、普通函数

1、直接调用普通函数

  • 普通函数类型的别名
#include <iostream>
#include<functional>
using namespace std;

using Fun = void(int, const string&); //普通函数类型的别名
Fun show;                             // 声明普通函数

// 上面2行等价于以下1行
//void show(int, const string&);        //声明普通函数

void show(int i, const string& message)
{
	cout << "第" << i << "个: " << message;
}

int main()
{
	show(1, "可能南方的阳光  照着北方的风"); //直接调用普通函数
}

 以下代码是错误的,不能用函数类型定义函数的实体。
//Fun show2(int i, const string& message)
//{
//	cout << "第" << i << "个: " << message;
//}

输出

第1个: 可能南方的阳光 照着北方的风

2、函数指针、函数引用

using Fun = void(int, const string&); //普通函数类型的别名
  • 用别名可以定义函数指针
Fun* fp1 = show;                     // 声明函数 指针,指向 普通函数
  • 用别名可以定义引用,
    我们很少使用函数引用,因为引用的本质是指针,所以他们是一样的。
`Fun& fr1 = show;                          // 声明函数 引用,引用 普通函数`
  • demo
#include <iostream>
#include<functional>
using namespace std;

using Fun = void(int, const string&);       //普通函数类型的别名
Fun show;                                   // 声明普通函数

// 上面2行等价于以下1行
//void show(int, const string&);            //声明普通函数

void show(int i, const string& message)
{
	cout << "第" << i << "个: " << message << endl;
}

int main() 
{
	// c++风格
	Fun* fp1 = show;                          // 声明函数 指针,指向 普通函数
	Fun& fr1 = show;                          // 声明函数 引用,引用 普通函数
	fp1(2, "可能西安城墙上  有人誓言不分");   // 用函数指针调用普通函数
	fr1(3, "可能西安城墙上  有人誓言不分");   // 用函数引用调用普通函数

	// c语言风格
	void(*fp2)(int, const string&) = show;    // 声明函数 指针,指向 普通函数
	void(&fr2)(int, const string&) = show;    // 声明函数 引用,引用 普通函数
	fp2(4, "可能要去到大理  才算爱得认真");   // 用函数指针调用普通函数
	fr2(5, "可能要去到大理  才算爱得认真");	  // 用函数引用调用普通函数
}

输出

第2个: 可能西安城墙上 有人誓言不分
第3个: 可能西安城墙上 有人誓言不分
第4个: 可能要去到大理 才算爱得认真
第5个: 可能要去到大理 才算爱得认真

三、仿函数——函数对象

  • 参考:【STL十四】函数对象(function object)_仿函数(functor)——lambda表达式
#include <iostream>
//
using namespace std;

class Print
{
public:
    void operator()(const char str[])
    {
        cout << str << endl;
    }
};

int main() {
    Print ob;
    ob("hello world");
    Print()("hello world"); //匿名函数对象

    Print& obr = ob;     //引用函数
    obr("hello world");  //用对象的引用调用仿函数
}

输出

hello world
hello world
hello world

四、lambda表达式

  • 参考:【STL十四】函数对象(function object)_仿函数(functor)——lambda表达式

五、类的静态成员函数——(作为可调用对象,没有实用价值)

#include <iostream>
using namespace std;

using Fun = void(int, const string&);  // 普通函数类型的别名。

struct AA	// 类中有静态成员函数。
{
	static void show(int bh, const string& message) {
		cout << "第" << bh << "个," << message << endl;
	}
};

int main()
{
	AA::show(6, " 可能(程响)");				   // 直接调用静态成员函数。

	Fun* fp1 = AA::show;						   // 用函数指针指向静态成员函数。
	Fun& fr1 = AA::show;						   // 引用静态成员函数。
	fp1(7, " 可能北京的后海  许多漂泊的魂");	   // 用函数指针调用静态成员函数。
	fr1(8, " 可能北京的后海  许多漂泊的魂");	   // 用函数引用调用静态成员函数。

	void(*fp2)(int, const string&) = AA::show;	   // 用函数指针指向静态成员函数。
	void(&fr2)(int, const string&) = AA::show;	   // 引用静态成员函数。
	fp2(9, " 可能成都小酒馆  有群孤独的人");	   // 用函数指针调用静态成员函数。
	fr2(10, "可能北京的后海  许多漂泊的魂");	   // 用函数引用调用静态成员函数。
}

输出

第6个, 可能(程响)
第7个, 可能北京的后海 许多漂泊的魂
第8个, 可能北京的后海 许多漂泊的魂
第9个, 可能成都小酒馆 有群孤独的人
第10个,可能北京的后海 许多漂泊的魂

六、类的非静态成员函数——(作为可调用对象,没有实用价值)

类的非静态成员函数= 类的普通成员函数

  • 类的非静态成员函数有地址,但是,只能通过类的对象才能调用它,所以,C++对它做了特别处理。

  • 类的非静态成员函数只有指针类型,没有引用类型,不能引用。

  • 普通成员函数指针 vs 类的成员函数的指针

// 普通成员函数
void(      *fp2)(int, const string&) = show;    // 声明函数 指针,指向 普通函数
// 类的成员函数
void (CC:: * fp1)(int, const string&) = &CC::show;		// 定义类的成员函数的指针。
  • 普通函数地址 vs 成员函数地址
// 普通函数地址
= show
= show
// 类的成员函数地址
= &CC::show
  • demo
#include <iostream>
using namespace std;

class CC	// 类中有普通成员函数。
{
public:
	void show(int bh, const string& message) {
		cout << "第" << bh << "行 ," << message << endl;
	}
};

int main()
{
	CC cc;
	cc.show(14, "可能(程响)");

	using pFun = void (CC::*)(int, const string&);		    // 类成员函数的指针类型。
	pFun fp2 = &CC::show;								    // 让类成员函数的指针指向类的成员函数的地址。
	(cc.*fp2)(15, "可能拥有过梦想  才能叫做青春");		    // 用类成员函数的指针调用类的成员函数。

	void (CC:: * fp1)(int, const string&) = &CC::show;		// 定义类的成员函数的指针。
	(cc.*fp1)(16, "可能拥有过梦想  才能叫做青春");			// 用类的成员函数的指针调用成员函数。
}

输出

第14行 ,可能(程响)
第15行 ,可能拥有过梦想 才能叫做青春
第16行 ,可能拥有过梦想 才能叫做青春

七、可被转换为函数的类的对象——(作为可调用对象,没有实用价值)

  • 实际开发中,没有意义,不做介绍。

参考
1、C++ STL 容器库 中文文档
2、STL教程:C++ STL快速入门
3、https://www.apiref.com/cpp-zh/cpp/header.html
4、https://en.cppreference.com/w/cpp/container
5、WIKI教程_C ++标准库_C++ Library - <iterator>
6、哔哩哔哩_系统化学习C++_C++11神器之可调用对象包装器和绑定器

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

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

相关文章

java错题总结(19-21页)

链接&#xff1a;关于Java中的ClassLoader下面的哪些描述是错误的_用友笔试题_牛客网 来源&#xff1a;牛客网 B&#xff1a;先讲一下双亲委派机制&#xff0c;简单来说&#xff0c;就是加载一个类的时候&#xff0c;会往上找他的父类加载器&#xff0c;父类加载器找它的父类加…

Centos系统安装RabbitMQ消息中间件

记录一下在centos7.x下面安装RabbitMQ消息中间件 RabbitMQ是一个开源而且遵循 AMQP协议实现的基于 Erlang语言编写&#xff0c;因此安装RabbitMQ之前是需要部署安装Erlang环境的 先安装Erlang https://packagecloud.io/rabbitmq/ 点进去可以看到 因为使用的centos是7.x版本的…

架构设计-数据库篇

大家好&#xff0c;我是易安&#xff01; 之前我们讲过架构设计的一些原则&#xff0c;和架构设计的方法论&#xff0c;今天我们谈谈高性能数据库集群的设计与应用。 读写分离原理 读写分离的基本原理是将数据库读写操作分散到不同的节点上&#xff0c;下面是其基本架构图。 读…

【Python系列】一个简单的抽奖小程序

序言 很开心你能在万千博文中打开这一篇&#xff0c;希望能给你带来一定的帮助&#xff01;&#x1f44d;&#x1f3fb; 如果有什么问题&#xff0c;都可以添加下方我的联系方式&#xff0c;联系我噢~&#x1f601; ⭐️⭐️⭐️⭐️⭐️沟通交流&#xff0c;一起成为技术达人&…

电视机顶盒哪个牌子好?数码小编盘点电视机顶盒排行榜

电视机顶盒哪个牌子好&#xff1f;这是困扰新手们的一大难题&#xff0c;部分产品被爆出虚标高配、偷工减料&#xff0c;面对众多的机顶盒品牌和型号&#xff0c;怎么选择才好&#xff1f;小编以销量和用户评价为标准&#xff0c;盘点了电视机顶盒排行榜&#xff0c;跟着我一起…

【Linux】进程学习(1)---理解进程概念

文章目录 冯诺依曼体系结构理解冯诺依曼体系结构 操作系统概念与定位概念计算机管理模型计算机的软硬件体系结构图系统调用和库函数概念 进程基本概念描述进程--PCBtask_struct内容分类组织进程 冯诺依曼体系结构 数学家冯诺依曼提出了计算机制造的三个基本原则&#xff0c;即采…

代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

文章目录 198.打家劫舍213.打家劫舍II337.打家劫舍III 198.打家劫舍 题目链接&#xff1a;代码随想录 解题思路&#xff1a; 1.dp[i]&#xff1a;考虑下标i&#xff08;包括i&#xff09;以内的房屋&#xff0c;最多可以偷窃的金额为dp[i] 只是考虑&#xff0c;不一定偷 2.递推…

GPT-4等大语言模型对教育的未来意味着什么?

‍ ‍ shadow Mixlab这些年举办了非常多的活动和workshop&#xff0c;都带有很强的教育属性。今天我抽空学习了可汗学院的《AI-for-Education》课程&#xff0c;非常有启发。我记录了精华内容&#xff0c;分享给大家。 课程地址&#xff1a; www.khanacademy.org/college-caree…

设计模式——观察者模式

导航&#xff1a; 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线设计模式牛客面试题 目录 观察者模式 1、天气预报需求 2、天气预报需求方案之普通方案 3、观察者模式介绍 4、观察者模式优化天气预报案例 5、JDK 的O…

销售数据分析怎么做?这篇文章说清楚了

如何分析销售数据&#xff1f;分析销售数据有哪些指标&#xff1f;销售数据分析有什么作用&#xff1f; 销售数据是不是得通过数据分析软件啊&#xff1f; 本文将为您解答疑惑—— 一、分析销售数据的指标 从两个层面上来讲&#xff0c;一个是对销售情况的整体把控&#xf…

红黑树理论详解与Java实现

文章目录 基本定义五大性质红黑树和2-3-4树的关系红黑树和2-3-4树各结点对应关系添加结点到红黑树注意事项添加的所有情况 添加导致不平衡叔父节点不是红色节点&#xff08;祖父节点为红色&#xff09;添加不平衡LL/RR添加不平衡LR/RL 叔父节点是红色节点&#xff08;祖父节点为…

破解马赛克有多「容易」?

刷短视频时&#xff0c;估计大家都看过下面这类视频&#xff0c;各家营销号争相曝光「一分钟解码苹果笔刷背后内容」的秘密。换汤不换药&#xff0c;自媒体们戏称其为「破解马赛克」&#xff0c;殊不知让多少不明真相的用户建立起了错误的认知&#xff0c;也让苹果笔刷第 10086…

【面试】嵌入式C语言题目整理

【面试】嵌入式C语言题目整理 描述内存四区。 内存四区分为&#xff1a;代码区、静态区、堆区、栈区 代码区就是用来存放代码的。 静态区用来存放全局变量、静态变量、常量&#xff08;字符串常量、const修饰的全局变量&#xff09;。 堆区中的内存是由程序员自己申请和释放的&…

九、MyBatis动态SQL

文章目录 九、动态SQL9.1 if9.2 where9.3 trim9.4 choose、when、otherwise9.5 foreach9.6 SQL片段 本人其他相关文章链接 九、动态SQL 9.1 if 总结&#xff1a;根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中。 User getUserByParamsWithIf(User user…

Packet Tracer - 在思科路由器上配置 AAA 认证

Packet Tracer - 在思科路由器上配置 AAA 认证 拓扑图 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 交换机端口 R1 G0/1 192.168.1.1 255.255.255.0 不适用 S1 F0/1 S0/0/0 (DCE) 10.1.1.2 255.255.255.252 不适用 不适用 R2 G0/0 192.168.2.1 255.2…

(四)Kubernetes - 手动部署(二进制方式安装)

Kubernetes - 手动部署 [ 3 ] 1 部署work node1.1 创建工作目录并拷贝二进制文件1.2 部署kubelet1.2.1 创建配置文件1.2.2 配置文件1.2.3 生成kubelet初次加入集群引导kubeconfig文件1.2.4 systemd管理kubelet1.2.5 启动并设置开机启动1.2.6 允许kubelet证书申请并加入集群 1.3…

JAVA-异常

文章目录 1.异常的体系1.3异常的分类 2.异常的处理2.2异常的抛出throw2.3异常的捕获2.3.1异常声明throws2.3.2 try-catch捕获并处理2.3.3 finally 2.4 异常的处理流程 3.自定义异常类 1.异常的体系 Throwable&#xff1a;是异常体系的顶层类&#xff0c;其派生出两个重要的子类…

人员拥挤检测系统 yolov5

人员拥挤检测系统通过YOLOv5网络模型算法技术&#xff0c;人员拥挤检测系统算法模型对校园/厂区车间/街道等场景的异常的人群聚集&#xff08;出现拥挤情况&#xff09;时&#xff0c;立刻抓拍存档并通知相关人员及时处理。在介绍Yolo算法之前&#xff0c;首先先介绍一下滑动窗…

ES是如何解决高可用

https://www.cnblogs.com/crazymakercircle/p/15433680.html ES是一个分布式全文检索框架&#xff0c;隐藏了复杂的处理机制&#xff0c;核心数据分片机制、集群发现、分片负载均衡请求路由。 ES的高可用架构&#xff0c;总体如下图&#xff1a; 说明&#xff1a;本文会以pdf…

Java 基础入门篇(一)—— Java 概述

文章目录 一、Java 概述二、Java 的产品 JDK2.1 JDK 安装2.2 Java与 Javac 介绍2.3 Java 程序的开发步骤 三、Java 程序的执行原理四、JDK 的组成五、Java 的跨平台工作原理 一、Java 概述 Java 是 sun 公司在 1995 年推出的一门计算机高级编程语言&#xff0c;其语言风格接近人…