【C++】仿函数(Functor)

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


核心概念

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

  2. 优势

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

基本实现

#include 

// 定义一个仿函数类
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 
    #include 
    
    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 
    std::function<int(int)> func = add5;
    std::cout << func(10);  // 输出15
    

总结

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

你可能感兴趣的:(C++,c++)