什么是函数对象
在C++中,函数对象(Function Object)又称仿函数(Functor),是通过定义 operator() 运算符重载的类或结构体实例,使其行为类似函数。它比普通函数更灵活,可存储状态(成员变量),支持泛型编程和算法定制。
核心特性
1. 重载 operator() :使类实例可像函数一样调用。
2. 可携带状态:通过成员变量存储数据,在调用时使用。
3. 类型安全:编译期确定行为,比函数指针更可靠。
4. 适配算法:可与STL算法(如 sort 、 for_each )结合使用。
代码示例
1. 基础函数对象(无状态)
cpp
#include <iostream>
using namespace std;
// 定义函数对象类(无状态)
class Add {
public:
int operator()(int a, int b) const { // 常成员函数
return a + b;
}
};
int main() {
Add add_obj; // 创建函数对象实例
int result = add_obj(3, 5); // 像函数一样调用
cout << "3 + 5 = " << result << endl; // 输出:8
return 0;
}
2. 带状态的函数对象
cpp
#include <iostream>
using namespace std;
// 带状态的函数对象:存储一个加数n
class Adder {
private:
int n; // 成员变量存储状态
public:
// 构造函数初始化状态
Adder(int num) : n(num) {}
// 重载()运算符,使用状态n
int operator()(int x) const {
return x + n;
}
};
int main() {
Adder add_10(10); // 创建加数为10的函数对象
cout << add_10(5) << endl; // 输出:15(5 + 10)
Adder add_20(20);
cout << add_20(5) << endl; // 输出:25(5 + 20)
return 0;
}
3. 与STL算法结合(排序自定义比较规则)
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 函数对象:降序比较
class CompareDesc {
public:
bool operator()(int a, int b) const {
return a > b; // 降序排列
}
};
int main() {
vector<int> nums = {3, 1, 4, 2};
// 使用函数对象作为排序的比较规则
sort(nums.begin(), nums.end(), CompareDesc());
for (int num : nums) {
cout << num << " "; // 输出:4 3 2 1
}
return 0;
}
4. 模板函数对象(泛型支持)
cpp
#include <iostream>
using namespace std;
// 模板函数对象:支持任意类型加法
template <typename T>
class GenericAdder {
public:
T operator()(T a, T b) const {
return a + b;
}
};
int main() {
GenericAdder<int> int_adder;
cout << int_adder(2, 3) << endl; // 输出:5(int类型)
GenericAdder<double> double_adder;
cout << double_adder(1.5, 2.5) << endl; // 输出:4(double类型)
return 0;
}
与普通函数的区别
表格
特性 普通函数 函数对象(仿函数)
状态存储 无 可通过成员变量存储状态
类型安全 运行时确定(函数指针) 编译期确定(类型明确)
可适配性 需通过函数指针或lambda 直接适配STL算法
扩展性 难以修改行为 可通过继承/模板扩展
应用场景
- STL算法定制:如 sort 的比较器、 transform 的操作函数。
- 策略模式:通过不同函数对象实现算法的动态切换。
- 状态化操作:需要携带上下文数据的函数逻辑(如累加器、计数器)。
C++的函数对象结合了面向对象和泛型编程的优势,是编写高效、灵活代码的重要工具。