C++语法|可调用对象和函数对象

server/2024/9/23 2:40:49/

在本文中,我想先详细讲解C++中的可调用对象和函数对象的定义,最后讲解二者的联系和区别

可调用对象

C++中,可调用对象(Callable Object)是一个可以被调用执行的对象,类似于函数。任何类型的对象,主要的可调用对象有以下几类:

1. 函数指针:指向函数的指针可以被调用。

2. 普通函数:直接定义的函数可以直接调用。

3. Lambda 表达式(本质是编译器为我们构造函数对象):C++11引入的Lambda允许创建匿名函数,它们是可调用的,其实在C++中,当我们创建一个lambda表达式,本质上是创建了一个未命名的类,而且这类是函数对象。

4. 函数对象(Functor):也叫仿函数,是一个行为类似函数的对象。这通常是通过在类中重载operator()来实现的,使得该类的实例可以像函数那样被调用。

5. 成员函数指针:指向类成员函数的指针,需要与一个对象实例一起使用。

**6. std::function:**是一个泛型函数包装器,可以存储、复制和调用任何类型的可调用对象,包括函数指针、Lambda表达式、函数对象等。

7. 绑定表达式:std::bind 创建的绑定表达式可以存储一个可调用对象及其参数,并在之后被调用。

函数指针

#include <iostream>
using namespace std;
void hello() {cout << "Hello, world!" << endl;
}int main() {void (*funcPtr)() = hello; // 函数指针funcPtr(); // 通过函数指针调用函数return 0;
}

Lambda表达式

具体关于Lambda表达式的内容可见:【C++语法】一起探讨 lambda 表达式!

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main() {vector<int> v = {1, 2, 3, 4, 5};int multiplier = 3;for_each(v.begin(), v.end(), [multiplier](int n) { cout << n * multiplier << endl; });return 0;
}

函数对象

通常是通过在类中重载operator()来实现的,使得该类的实例可以像函数那样被调用

#include <iostream>
using namespace std;class Multiply {
public:Multiply(int y) : multiplier(y) {}int operator()(int x) const {return x * multiplier;}
private:int multiplier;
};int main() {Multiply multiplyBy2(2);cout << "2 multiplied by 2 is " << multiplyBy2(2) << endl;return 0;
}

成员函数指针

指向类成员函数的指针,需要与一个对象实例一起使用。

#include <iostream>
using namespace std;class Greeter {
public:void greet() {cout << "Hello from Greeter!" << endl;}
};int main() {Greeter greeter;void (Greeter::*funcPtr)() = &Greeter::greet; // 成员函数指针(greeter.*funcPtr)(); // 调用成员函数return 0;
}

std::function

更多关于function类型的详情可见:

#include <iostream>
#include <functional>
using namespace std;void printSum(int a, int b) {cout << "Sum: " << a + b << endl;
}int main() {function<void(int, int)> func = printSum; // function 可以存储普通函数func(5, 3); // 使用 function 调用函数return 0;
}

函数对象

在C++中,函数对象(通常被称为functor)是指任何可以通过函数调用运算符()被调用的对象。具体而言,这意味着在类中实现了重载的operator()成员函数的任何对象都可以被视为函数对象。这使得对象在语法上表现得像一个普通函数

函数对象的主要优点是它们比普通函数更灵活,因为它们可以拥有状态。通过在类内部保持状态,函数对象可以在多次调用之间保持信息。此外,它们还可以利用面向对象的特性,如封装和继承。

函数对象在C++标准库中广泛使用,尤其是在算法库中,如std::sort或std::for_each等算法可以接受自定义的函数对象作为参数,以定义特定的行为。此外,函数对象也常用于实现回调和绑定事件

典型例子

#include <iostream>class Adder {
public:// 构造函数,可选地初始化加数Adder(int initValue = 0) : value(initValue) {}// 重载函数调用运算符int operator()(int x) {return x + value;}private:int value;
};int main() {Adder addFive(5);  // 创建一个Adder对象,初始值为5std::cout << "Result: " << addFive(3) << std::endl;  // 输出8,因为 3 + 5 = 8return 0;
}

http://www.ppmy.cn/server/39527.html

相关文章

【已解决】chrome/其他浏览器:你的连接不是私密连接

一、问题原因 这个问题一般是https的网址会有&#xff0c;它是安全的访问连接&#xff0c;在原来的基础上SSL/TLS协议进行加密和身份验证。 这里可能是证书过期了&#xff0c;其实 二、解决方法【亲测有效】 方法1&#xff1a;点击高级&#xff0c;如果有继续访问对应的http…

第Ⅷ章-Ⅰ 组合式API初识

第Ⅷ章-Ⅰ 组合式API初识 简介setup 函数 为什么要使用Composition API逻辑复用和组织更灵活的逻辑组合适应未来的 Vue 生态系统 options API存在的问题代码重复&#xff1a;逻辑分散缺乏复用性 Composition API 中的 setup()入口props 参数context 参数 ref 响应式监听reactiv…

Elastic Stack--04-1--Kibana查数

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Kibana查数1.查询所有记录2.匹配id字段matchterm 3.bool[复合查询]4.业务查询 Kibana查数 在ElasticSearch中支持两种检索方式 通过使用REST request URL 发送检索…

神经网络与空间变换关系

神经网络的隐藏层实际上就是在进行一次空间变换&#xff0c;隐藏层中神经元的个数就是变换后空间的维度&#xff0c;代表可以升维也可以降维。 不同是 神经网络的一层运算不只有矩阵乘法&#xff0c;还会有一个加法。以及 进行完线性计算后&#xff0c;还要经过非线性的激活函…

sdut java lab7.2

7-2 sdut-JAVA-Words Containing AB 分数 9 全屏浏览 切换布局 作者 马新娟 单位 山东理工大学 Write a program that requests a word as input containing the two letters a and b (in this order). Examples of valid words would include, abacus, cab, and anybody, …

【MySQL基本查询(下)】

文章目录 一、update案例 二、Delete案例注意&#xff1a;delete 全表数据的行为慎用&#xff01;truncate 三、插入查询结果案例 四、了解一些函数1.count函数2.sum函数3. avg函数4.max函数5. min函数 五、group by子句的使用案例having和where 一、update 该关键字的功能就是…

ExcelVBA取序号与合计之间的数据

今天有人提出这样一个问题&#xff0c; ExcelVBA取序号与合计之间的数据 数据如下: 分析一下&#xff0c;问题关键&#xff1a; 问题&#xff1a;1.我要在“序号”两字后面开始取数&#xff0c;因为序号是合并的&#xff0c;所以。。。2.我要取合计前面的数据&#xff0c;所以要…

SpringCloud生态体系介绍

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用Spring Boot的开发风格做到一键启动和部署。 SpringC…