C++函数对象是指重载了函数调用运算符operator()的类或结构体实例,这类对象可以像普通函数一样被调用,同时还能携带自身的状态信息,比普通函数更加灵活,在STL算法、事件回调等场景中有广泛应用。

函数对象的基本实现规则
要实现函数对象,只需要在类或结构体中定义operator()运算符的重载函数即可,该重载函数的参数和返回值可以根据实际需求自定义,和普通函数的参数、返回值规则一致。
需要注意operator()是运算符重载,不是类的构造函数,定义时需要遵循运算符重载的语法规范,不能修改运算符的原有调用逻辑。
最简单的无参数函数对象示例
下面是一个无参数、无返回值的函数对象实现,调用时会输出固定提示信息:
#include <iostream>
using namespace std;
// 定义函数对象类
struct PrintHello {
// 重载operator()运算符
void operator()() const {
cout << "Hello from function object" << endl;
}
};
int main() {
// 创建函数对象实例
PrintHello printObj;
// 像调用函数一样使用实例
printObj();
// 也可以直接调用临时对象的operator()
PrintHello()();
return 0;
}
带参数和返回值的函数对象示例
函数对象的operator()可以支持任意数量和类型的参数,也可以返回对应类型的结果,下面是一个实现两数相加的函数对象:
#include <iostream>
using namespace std;
// 带模板的函数对象,支持不同数值类型
template <typename T>
struct Adder {
T operator()(T a, T b) const {
return a + b;
}
};
int main() {
Adder<int> intAdder;
cout << "1 + 2 = " << intAdder(1, 2) << endl;
Adder<double> doubleAdder;
cout << "3.5 + 4.2 = " << doubleAdder(3.5, 4.2) << endl;
return 0;
}
带状态的函数对象实现
函数对象相比普通函数的最大优势是可以携带状态,类中的成员变量可以记录函数对象的调用状态,下面是一个统计调用次数的函数对象示例:
#include <iostream>
using namespace std;
struct CallCounter {
int count; // 记录调用次数
CallCounter() : count(0) {}
void operator()() {
count++;
cout << "函数对象已被调用 " << count << " 次" << endl;
}
};
int main() {
CallCounter counter;
counter();
counter();
counter();
return 0;
}
函数对象在STL算法中的应用
STL的很多算法都支持传入函数对象作为自定义操作逻辑,比如std::sort可以传入自定义的比较函数对象,下面是一个按降序排序的示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 降序比较函数对象
struct DescCompare {
bool operator()(int a, int b) const {
return a > b;
}
};
int main() {
vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6};
// 传入函数对象作为排序规则
sort(nums.begin(), nums.end(), DescCompare());
for (int num : nums) {
cout << num << " ";
}
cout << endl;
return 0;
}
函数对象的注意事项
- operator()重载函数的const修饰:如果不需要修改函数对象的状态,建议将operator()声明为const成员函数,这样可以让函数对象在const场景下正常使用。
- 函数对象可以内联:编译器通常会对函数对象的operator()调用进行内联优化,执行效率比普通函数指针更高。
- 函数对象和lambda表达式的关系:C++11引入的lambda表达式本质就是编译器自动生成的函数对象,二者核心逻辑是一致的。
C++函数对象operator()重载函数对象示例C++仿函数修改时间:2026-07-01 11:48:28