函数对象
定义:若在一个类中重载了小括号运算符,当使用这个类去定义一个对象时,称这个对象为函数对象。其目的在于提高效率,如果类中的成员函数简短且没有循环的时候,编译器就会将其提升为内联函数。
代码如下:
#include <iostream>
using namespace std;
template <class T>
class A
{
private:
T num;
public:
A(T _num){
this->num = _num;
}
void operator()()
{
cout << this->num <<endl;
}
};
int main()
{
A<string> a("hello world!!!");
a();
a.operator()();
return 0;
}
执行结果:
此时代码中所定义的 a 其实是一个临时对象。
何为临时对象?
当我们在栈上定义对象时,只调用类中的构造函数时,编译器就会定义一个临时对象,这个对象只有空间没有地址,生命周期也非常短暂,即执行完它的下一行代码,就会被析构。
代码如下:
#include <iostream>
using namespace std;
class S
{
public:
S(){
cout << "S 的构造" << endl;
}
virtual ~S(){
cout << "S 的析构" << endl;
}
S(const S&){
cout << "S 的拷贝构造" << endl;
}
virtual void show(){
cout << "1111" << endl;
}
};
class Q : public S
{
public:
Q(){
cout << "Q 的构造" << endl;
}
~Q(){
cout << "Q 的析构" << endl;
}
void show(){
cout << "2222" << endl;
}
};
int main()
{
S num = Q();
num.show();
return 0;
}
执行结果:
执行结果的前两个构造就是在创建临时对象,当执行完拷贝构造时,就会被立即析构,最后一个析构是拷贝构造的
函数对象的用法:
#include <iostream>
using namespace std;
template <class T>
T my_less(T t1,T t2)
{
return t1 > t2 ? t1 : t2;
}
template <class T, class Text>
T compair(T t1, T t2, Text t)
{
return t(t1, t2);
}
template <class T>
class My_Less
{
public:
int operator()(T t1, T t2)
{
return t1 > t2 ? t1 : t2;
}
};
int main()
{
int a = 10;
int b = 20;
cout << compair(a, b, my_less<int>) <<endl;
cout << "--------------" << endl;
cout << compair(a, b, My_Less<int>()) << endl;
return 0;
}
当小括号运算符中只有一个参数,使用这个类所定义的对象叫一元函数对象。
当小括号运算符中只有两个参数,使用这个类所定义的对象叫二元函数对象。
当小括号运算符中有多个参数,使用这个类所定义的对象叫多元函数对象。
另外小括号运算符函数返回值为布尔类型(bool)时,这个函数对象也叫谓词(Predicate)
一个参数叫一元谓词,两个参数叫二元谓词。因为类型是布尔,所以没有多元一说。
注:
在C++中Funtor也被称为函数符:
函数符就有四种表现形式:
1.全局函数指针,2.成员函数指针,3.函数对象,4.Lambda匿名函数对象(Lambda表达式)。
匿名函数
既然称为匿名函数,说明没有名字只是临时调用,当使用完后,系统就会自动释放内存,继而提升内存的利用效率。
#include <iostream>
using namespace std;
template <class T = int> //可以指定类型
class A
{
int num;
public:
A(int& n){
this->num = n;
}
void operator()(){
cout << num << endl;
cout << "hello world!!!" << endl;
}
};
int main()
{
int aa = 10;
A<> a(aa);
a();
a.operator()();
auto f = []()->void{ cout << "hello-------" << endl; };
f();
//auto 是编译器自动推导类型关键字,但不可用在函数中
//[]:表示函数对象的构造函数中是否接收外部变量;
//[&]:表示使用引用的方式获取外部变量
//[=]:表示使用值的拷贝的方式获取外部变量
//():这个小括号就是函数对象中的小括号符后面的参数列表
//->:返回值,需要就放,不需要可以不放
//{...}:就是函数对象的小括号运算符的函数体
int x = 100;
int y = 120;
auto f1 = [&]()
{
int temp = x;
x = y;
y = temp;
};
f1();
cout << "x= " << x << " y= " << y << endl;
return 0;
}