函数对象就是类对象,生成这个类对象的类中,拥有一个小括号运算符重载函数。
重载了小括号运算符的类的类对象,就叫函数对象。
- #include
-
- using namespace std;
-
- template <class T1>
- class A
- {
- T1 name;
- public:
- A(T1 name)
- {
- this->name=name;
- }
-
- void operator()()
- {
- cout<<this->name<
- }
- };
-
- int main()
- {
- A
a("da jia hao") ; -
- a();
-
- return 0;
- }
1.3函数对象相较于普通函数与函数指针的调用效率要高很多(
1.3.1当我们用普通函数的时候:像下面这种情况,每次都需要回调,特别的繁琐。
注意:在这个代码里面,即使我们在函数前面都加上inline变成内联函数,也是不行的,因为我们使用的是函数指针,即使变成了内联函数,我们还是需要回调。
- #include
-
- using namespace std;
- template <class T>
- T my_bigger(T a,T b)
- {
- return a>b?a:b;
- }
-
- template <class T>
- T my_less(T a,T b)
- {
- return a>b?b:a;
- }
-
- template <class T,class Compare>
- T my_compare(T a, T b,Compare f)
- {
- return f(a,b);
- }
-
- int main()
- {
- cout<< my_compare<int>(10,20,my_less<int>)<
- cout<<my_compare<int>(10,20,my_bigger<int>)<
-
-
- return 0;
- }
1.3.2使用函数对象就可以解决这个问题,因为使用函数对象就相当于在函数面前加上一个inline,效率会提升,代码如下:
- #include
-
- using namespace std;
-
-
- template <class T,class Compare>
- T my_compare(T a, T b,Compare f)
- {
- return f(a,b);
- }
-
- template <class T>
- class A
- {
- public:
- T operator()(T a,T b)
- {
- return a>b?a:b;
- }
- };
-
- template <class T>
- class B
- {
- public:
- T operator()(T a,T b)
- {
- return a>b?b:a;
- }
- };
-
- int main()
- {
- cout<<my_compare(10,20,A<int>())<
- cout<<my_compare(10,20,B<int>())<
- return 0;
- }
2.匿名函数对象Lambda表达式:
2.1使用形式:
auto + 名字 =[]()->返回值{};
具体介绍:
1.[] 中括号表示函数对象的构造函数中是否接收外部变量。 [&] ,表示使用引用的方式获取外部变量 [=],表示使用值的拷贝的方式获取外部变量。
2.() 这个小括号是就函数对象中的小括号符后面的参数列表。
3.->返回值,需要就放,不需要就不放。根据自己需要,任君选择。
4.{...} 就是函数对象的小括号运算符的函数体。
2.2代码实例:
2.2.1第一个当[]里面没用东西时:
- #include
-
- using namespace std;
- class A
- {
- public:
- A()
- {
-
- }
-
- void operator()()
- {
-
- }
- };
-
-
- int main()
- {
-
- auto f=[]()->void{cout<<"我是大哥"<
- f();
-
- return 0;
- }
2.2.2第二个当[]里面有东西时:(实现交换)
- #include
-
- using namespace std;
- class A
- {
- int a;
- public:
- A(int &a)
- {
- this->a=a;
- }
-
- void operator()()
- {
-
- }
- };
-
-
- int main()
- {
-
- int a=10;
- int b=20;
-
- auto f=[&]()->void
- {
- int temp=a;
- a=b;
- b=temp;
- };
-
- f();
-
- cout<
- return 0;
- }
2.2.3注意点:
当时候=号的时候,底层实现用的是const,这样就不能进行赋值等一系列操作,如下代码,我们可以加上一个mutable,C++11所提供的新的关键字mutale,是一种易变是的修饰符。当然下面这个代码肯定不能实现交换,我只是用来做一个说明。
- #include
-
- using namespace std;
- class A
- {
- int a;
- public:
- A(int &a)
- {
- this->a=a;
- }
-
- void operator()()
- {
-
- }
- };
-
-
- int main()
- {
-
- int a=10;
- int b=20;
-
- auto f=[=]()mutable
- {
- int temp=a;
- a=b;
- b=temp;
- };
-
- f();
-
-
- return 0;
- }
3总结:
在C++中Funtor也被称为函数符:
函数符就有四种表现形式:
1.全局函数指针,2.成员函数指针,3.函数对象,4.Lambda匿名函数对象(Lambda表达式)。
-
相关阅读:
基于springboot实现数码论坛系统设计与实现系统【项目源码+论文说明】计算机毕业设计
垃圾收集算法
前端技能树,面试复习第 51 天—— Vue 项目性能优化方案
什么是重绘和回流(重排)?什么情况下会用到?如何减少
分布式数据库难题(一):数据分区
大学计算机毕业设计真的很难完成吗?(资源持续更新~~)
【毕业设计】56-辅助驾驶系统的视觉检测\超声波\图像识别\装置研究与设计(原理图工程、仿真工程、低重复率设计文档、答辩PPT、开题报告)
ssm基于java的儿童成长记录系统
基于Java+SpringBoot+Vue前后端分离秒杀系统设计和实现
汉堡炸鸡快餐店商城小程序的作用是什么
-
原文地址:https://blog.csdn.net/a2998658795/article/details/126068605