【C++】仿函数(Functor)

在 C++ 中,仿函数(Functor) 是一种特殊的对象,它通过重载 operator() 运算符使得类的实例可以像函数一样被调用。仿函数结合了面向对象和函数式编程的特点,常用于 STL 算法、回调机制和策略模式中。


核心概念

  1. 本质
    仿函数是一个类或结构体,通过定义 operator() 运算符,使对象可以像函数一样被调用。

  2. 优势

    • 状态保持:可以保存内部状态(普通函数无法做到)。
    • 灵活性:可作为参数传递,比函数指针更安全、更高效(支持内联优化)。
    • 模板友好:泛型编程中兼容性更好。

基本实现

#include <iostream>

// 定义一个仿函数类
class Adder {
public:
    Adder(int value) : increment(value) {}
    
    // 重载 operator()
    int operator()(int x) const {
        return x + increment;
    }

private:
    int increment;
};

int main() {
    Adder add5(5);      // 创建一个仿函数对象,每次加5
    std::cout << add5(10);  // 输出 15(调用 add5.operator()(10))
    return 0;
}

仿函数 vs 函数指针

特性仿函数函数指针
状态保持✔️ 可以保存成员变量❌ 无法保持状态
内联优化✔️ 编译器可能内联❌ 通常无法内联
泛型编程✔️ 类型安全,适用于模板❌ 类型转换可能不安全
灵活性✔️ 可定义多种操作的重载❌ 只能指向固定签名的函数

应用场景

  1. STL 算法
    仿函数广泛用于 STL 算法的自定义行为,例如排序、查找、变换等。

    #include <algorithm>
    #include <vector>
    
    struct Compare {
        bool operator()(int a, int b) const {
            return a > b;  // 降序排序
        }
    };
    
    int main() {
        std::vector<int> nums = {3, 1, 4, 1, 5};
        std::sort(nums.begin(), nums.end(), Compare());
        return 0;
    }
    
  2. 策略模式
    通过传递不同的仿函数对象,动态改变算法行为。

    template <typename Strategy>
    void processData(Strategy strategy) {
        // 使用策略处理数据
        strategy.apply();
    }
    
    class FastStrategy {
    public:
        void apply() { /* 快速处理逻辑 */ }
    };
    
    class SafeStrategy {
    public:
        void apply() { /* 安全处理逻辑 */ }
    };
    
  3. 状态保持
    保存多次调用的中间状态。

    class Counter {
    public:
        Counter() : count(0) {}
        int operator()() { return ++count; }
    private:
        int count;
    };
    
    Counter cnt;
    cnt();  // 返回1
    cnt();  // 返回2
    

C++11 后的增强

  1. Lambda 表达式
    Lambda 本质上是匿名仿函数,语法更简洁:

    auto add5 = [value=5](int x) { return x + value; };
    std::cout << add5(10);  // 输出15
    
  2. std::function
    通用函数包装器,可存储仿函数、Lambda、函数指针等:

    #include <functional>
    std::function<int(int)> func = add5;
    std::cout << func(10);  // 输出15
    

总结

  • 仿函数是 C++ 中强大的工具,结合了对象和函数的特性。
  • 在需要状态保持、模板编程或策略模式时,优先考虑仿函数。
  • 现代 C++ 中,Lambda 和 std::function 提供了更简洁的替代方案,但底层原理一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴雨日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值