函数对象(仿函数)和匿名函数,知识总结

本文介绍了C++中的函数对象,包括如何通过重载小括号运算符创建函数对象,以及它们在提高效率方面的应用。此外,解释了临时对象的概念,即在栈上定义对象时由编译器生成的短暂对象。最后,讨论了匿名函数(Lambda表达式)的使用,展示了其在代码中的功能和内存管理优势。
摘要由CSDN通过智能技术生成

函数对象

        定义:若在一个类中重载了小括号运算符,当使用这个类去定义一个对象时,称这个对象为函数对象。其目的在于提高效率,如果类中的成员函数简短且没有循环的时候,编译器就会将其提升为内联函数。

代码如下:

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值