跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 函数对象概述
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:C++函数对象概述}} == 简介 == '''函数对象(Function Object)''',也称为'''仿函数(Functor)''',是C++标准模板库(STL)中的一个重要概念。它是一个行为类似函数的对象,通过重载<code>operator()</code>运算符实现。函数对象可以像普通函数一样被调用,但具有对象的特性(如可以存储状态、继承等)。 函数对象在STL中广泛应用,例如在<code>std::sort</code>、<code>std::for_each</code>等算法中作为自定义比较或操作逻辑的载体。 == 基本语法 == 函数对象的核心是重载<code>operator()</code>,使其成为一个可调用的对象。以下是一个简单的函数对象示例: <syntaxhighlight lang="cpp"> #include <iostream> // 定义一个函数对象类 struct Adder { int operator()(int a, int b) const { return a + b; } }; int main() { Adder adder; // 创建函数对象实例 std::cout << adder(3, 4) << std::endl; // 输出: 7 return 0; } </syntaxhighlight> === 输出 === <pre> 7 </pre> == 函数对象的优势 == 与普通函数相比,函数对象具有以下优势: 1. '''状态保持''':函数对象可以存储内部状态(通过成员变量)。 2. '''灵活性''':可以作为模板参数传递,支持更复杂的逻辑。 3. '''性能''':编译器可以内联优化,减少函数调用开销。 === 示例:带状态的函数对象 === <syntaxhighlight lang="cpp"> #include <iostream> class Counter { int count = 0; public: int operator()() { return ++count; } }; int main() { Counter counter; std::cout << counter() << std::endl; // 输出: 1 std::cout << counter() << std::endl; // 输出: 2 return 0; } </syntaxhighlight> === 输出 === <pre> 1 2 </pre> == STL中的函数对象 == C++标准库提供了许多预定义的函数对象(在<code><functional></code>头文件中),例如: * <code>std::less</code>(比较) * <code>std::plus</code>(加法) * <code>std::negate</code>(取反) === 示例:使用STL函数对象 === <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> int main() { std::plus<int> add; std::cout << add(5, 3) << std::endl; // 输出: 8 std::less<int> compare; std::cout << compare(2, 5) << std::endl; // 输出: 1 (true) return 0; } </syntaxhighlight> === 输出 === <pre> 8 1 </pre> == 函数对象与Lambda表达式 == C++11引入的Lambda表达式是匿名函数对象的语法糖。以下示例展示了两者的等价性: <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> nums = {3, 1, 4, 1, 5}; // 使用函数对象 struct { bool operator()(int a, int b) const { return a > b; } } customGreater; std::sort(nums.begin(), nums.end(), customGreater); // 等价Lambda表达式 std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); for (int n : nums) std::cout << n << " "; return 0; } </syntaxhighlight> === 输出 === <pre> 5 4 3 1 1 </pre> == 实际应用案例 == === 案例1:自定义排序 === 在数据分析中,可能需要按特定规则排序: <syntaxhighlight lang="cpp"> #include <algorithm> #include <vector> #include <string> struct Person { std::string name; int age; }; // 按年龄升序排序的函数对象 struct AgeSorter { bool operator()(const Person& a, const Person& b) const { return a.age < b.age; } }; int main() { std::vector<Person> people = {{"Alice", 30}, {"Bob", 25}, {"Charlie", 35}}; std::sort(people.begin(), people.end(), AgeSorter()); // 结果: Bob(25), Alice(30), Charlie(35) return 0; } </syntaxhighlight> === 案例2:数学函数组合 === 函数对象可以实现数学函数的组合: <syntaxhighlight lang="cpp"> #include <iostream> #include <cmath> // 函数对象组合示例 template <typename F1, typename F2> class Compose { F1 f1; F2 f2; public: Compose(F1 f1, F2 f2) : f1(f1), f2(f2) {} template <typename T> auto operator()(T x) const { return f1(f2(x)); } }; int main() { auto square = [](double x) { return x * x; }; auto sin_then_square = Compose(square, (double(*)(double))std::sin); std::cout << sin_then_square(3.14159/2) << std::endl; // 输出: ~1.0 return 0; } </syntaxhighlight> == 性能考虑 == 函数对象通常比函数指针更高效,因为: * 编译器可以内联调用 * 避免了间接调用的开销 以下mermaid图展示了函数对象的调用流程: <mermaid> graph LR A[调用代码] --> B[operator()] B --> C[执行函数体] </mermaid> == 进阶主题 == 对于高级用户,函数对象还可以: 1. 通过模板参数化(如<code>std::function</code>) 2. 实现柯里化(Currying) 3. 与SFINAE技术结合 数学表示示例(函数组合): <math> (f \circ g)(x) = f(g(x)) </math> == 总结 == 函数对象是C++中强大的抽象工具,它: * 结合了函数和对象的优点 * 在STL算法中广泛使用 * 提供了比函数指针更灵活、更高效的解决方案 掌握函数对象是深入理解C++泛型编程和STL设计哲学的关键步骤。 [[Category:编程语言]] [[Category:C++]] [[Category:C++stl 函数对象]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)