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

embedded/2024/12/23 1:39:11/

在本文中,我想先详细讲解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/embedded/40826.html

相关文章

SQLZOO:Using Null

数据表&#xff1a;teacher-dept teacher iddeptnamephonemobile1011Shrivell275307986 555 12341021Throd275407122 555 19201031Splint2293104Spiregrain32871052Cutflower321207996 555 6574106Deadyawn3345... dept idname1Computing2Design3Engineering... Q1 List the t…

linux进阶篇:Nginx反向代理原理与案例详解

Linux服务搭建篇&#xff1a;Nginx反向代理原理与案例详解 一、什么是正向代理 举个栗子&#xff1a; 我们在校外、公司外&#xff0c;是访问不到学校、公司的内网的&#xff0c;但是我们想要访问内网资源时&#xff0c;会用到VPN。而一般内网会存在一个VPN服务器&#xff0c…

猫头虎分享已解决Error || ERROR: Failed building wheel for XXX

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

规则引擎简单介绍以及与设计模式之间的关系

一、什么是规则引擎 定义&#xff1a;是指对业务系统的规则进行抽象&#xff0c;使之成为通用模型。 作用&#xff1a;帮助应用程序开发人员构建一套标准化的业务规则和算法。 规则引擎可以简化业务架构&#xff0c;让开发人员更容易理解业务逻辑&#xff0c;并在一个开发环…

STM32快速入门(定时器之输入捕获)

STM32快速入门&#xff08;定时器之输入捕获&#xff09; 前言 本节主要讲解STM32利用通用定时器&#xff0c;在输入引脚出现指定电平跳变时&#xff0c;将CNT的值锁存到CCR寄存器当中&#xff0c;从而计算PWM波形的频率、占空比、脉冲间隔、电平持续时间等。其功能的应用有&…

vue3 自定义调控参数-简易生成器

vue3 自定义调控参数-简易生成器 文章目录 封装生成器控件如下父组件使用如下&#xff1a; 此功能好像是某厂的在线视频笔试题&#xff0c;当时写完也没有结果。。。我觉得此 demo 适用场景&#xff1a;自定义动态表单时需要定制字段、用户自定义信息等 封装生成器控件如下 /…

白盒测试:覆盖测试及测试用例设计

白盒测试&#xff1a;覆盖测试及测试用例设计 一、实验目的 1、掌握白盒测试的概念。 2、掌握逻辑覆盖法。 二、实验任务 某工资计算程序功能如下&#xff1a;若雇员月工作小时超过40小时&#xff0c;则超过部分按原小时工资的1.5倍的加班工资来计算。若雇员月工作小时超过…

Cocos Creator 3.8.x报错:5302

在小游戏加载某个bundle后&#xff0c;如果报以下错误&#xff1a; 5302&#xff1a;Can not find class %s 说明bundle中某个预制件*.prefab引用了未加载的bundle的资源。 解决方法有两个&#xff1a; 1、将引用的资源移到预制件*.prefab相同的bundle下&#xff1b; 2、将…