2023-09-25 03:57:57
函数对象是通过重载operator()实现的可调用对象,能携带状态,常用于STL算法中传递带上下文的行为,支持状态保持、类型封装和复用,适用于自定义比较器、谓词及策略模式等场景。
实例化后可直接调用:
Multiplier multiplyBy5(5);std::cout << multiplyBy5(10); // 输出50每个实例可携带独立状态(如factor),实现行为与状态的结合。
与普通函数的区别
状态保持:普通函数无状态,行为仅由输入决定;函数对象可通过成员变量存储状态,多次调用间可累积或共享数据。
类型封装:函数对象是具体类型,可作为模板参数传递,支持类型安全的泛型编程;普通函数需通过函数指针传递,缺乏类型信息。
复用性:函数对象可定义复杂逻辑并复用,普通函数需重复编写或依赖全局变量。
与Lambda表达式的区别
命名与复用:Lambda是匿名临时对象,适合简单场景;函数对象可命名,便于复用和调试。
多态性:函数对象可参与继承体系,实现多态行为;Lambda需通过std::function间接支持多态。
编译优化:显式函数对象类型可能触发更彻底的编译器优化。
调试友好性:具名函数对象在调试时更易识别。
典型应用场景
STL算法定制:作为比较器、谓词或转换逻辑。例如:
策略模式:不同函数对象代表不同算法策略,通过多态切换行为。
回调封装:在旧代码库或C风格API中封装回调逻辑(现代C++更推荐std::function)。
优势总结函数对象通过状态保持、类型封装和复用性,解决了普通函数和Lambda在泛型编程中的局限性。在需要传递复杂行为、维护上下文或参与类型系统时,函数对象仍是高效且灵活的选择。