跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 函数对象
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:C++函数对象}} '''C++函数对象'''(Function Object),又称'''仿函数'''(Functor),是C++中一种重要的编程概念,它允许对象像函数一样被调用。本文将详细介绍函数对象的定义、实现方式、应用场景及其与普通函数的区别。 == 介绍 == 在C++中,函数对象是一个类或结构体,它重载了函数调用运算符<code>operator()</code>。通过这种方式,对象可以像函数一样被调用。函数对象的主要优势在于它可以存储状态(成员变量),并且可以在运行时动态调整行为。 函数对象通常用于: * 标准库算法(如<code>std::sort</code>、<code>std::transform</code>)的自定义比较或操作。 * 回调机制。 * 实现闭包(Closure)功能。 == 基本语法与示例 == 以下是一个简单的函数对象示例: <syntaxhighlight lang="cpp"> #include <iostream> // 定义一个函数对象类 class Adder { public: Adder(int increment) : increment_(increment) {} // 重载 operator() int operator()(int x) const { return x + increment_; } private: int increment_; }; int main() { Adder add5(5); // 创建一个函数对象,每次调用加5 std::cout << add5(10) << std::endl; // 输出: 15 std::cout << add5(20) << std::endl; // 输出: 25 return 0; } </syntaxhighlight> '''输出:''' <pre> 15 25 </pre> === 解释 === 1. <code>Adder</code> 是一个函数对象类,它包含一个成员变量 <code>increment_</code>。 2. <code>operator()</code> 被重载,使得对象可以像函数一样被调用。 3. 在 <code>main()</code> 中,<code>add5</code> 是一个函数对象实例,调用 <code>add5(10)</code> 相当于调用 <code>operator()(10)</code>。 == 函数对象 vs 普通函数 == 函数对象与普通函数相比具有以下优势: 1. '''可以存储状态''':函数对象可以包含成员变量,而普通函数只能通过全局变量或静态变量存储状态。 2. '''可以作为模板参数''':函数对象可以作为模板参数传递,而普通函数需要通过函数指针。 3. '''性能优化''':编译器可以内联函数对象的调用,而函数指针可能无法内联。 === 示例:比较函数对象与函数指针 === <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> // 普通函数 bool compare(int a, int b) { return a > b; } // 函数对象 struct Compare { bool operator()(int a, int b) const { return a > b; } }; int main() { std::vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6}; // 使用普通函数 std::sort(nums.begin(), nums.end(), compare); // 使用函数对象 std::sort(nums.begin(), nums.end(), Compare()); for (int num : nums) { std::cout << num << " "; } std::cout << std::endl; return 0; } </syntaxhighlight> '''输出:''' <pre> 9 6 5 4 3 2 1 1 </pre> == 实际应用场景 == 函数对象在C++标准库中广泛使用,尤其是在算法(<code><algorithm></code>)中。以下是几个常见用例: === 1. 自定义排序 === <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> struct CaseInsensitiveCompare { bool operator()(const std::string& a, const std::string& b) const { return std::lexicographical_compare( a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { return tolower(c1) < tolower(c2); } ); } }; int main() { std::vector<std::string> words = {"Apple", "banana", "Cherry", "date"}; std::sort(words.begin(), words.end(), CaseInsensitiveCompare()); for (const auto& word : words) { std::cout << word << " "; } std::cout << std::endl; return 0; } </syntaxhighlight> '''输出:''' <pre> Apple banana Cherry date </pre> === 2. 生成器模式 === 函数对象可以用于生成序列: <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> class SequenceGenerator { public: SequenceGenerator(int start, int step) : current_(start), step_(step) {} int operator()() { int value = current_; current_ += step_; return value; } private: int current_; int step_; }; int main() { std::vector<int> sequence(10); std::generate(sequence.begin(), sequence.end(), SequenceGenerator(0, 2)); for (int num : sequence) { std::cout << num << " "; } std::cout << std::endl; return 0; } </syntaxhighlight> '''输出:''' <pre> 0 2 4 6 8 10 12 14 16 18 </pre> == Lambda表达式与函数对象 == C++11引入了Lambda表达式,它本质上是匿名函数对象的语法糖。以下示例展示了Lambda与函数对象的等价性: <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> nums = {1, 2, 3, 4, 5}; // 使用Lambda表达式 std::for_each(nums.begin(), nums.end(), [](int x) { std::cout << x * x << " "; }); std::cout << std::endl; // 等价函数对象 struct SquarePrinter { void operator()(int x) const { std::cout << x * x << " "; } }; std::for_each(nums.begin(), nums.end(), SquarePrinter()); std::cout << std::endl; return 0; } </syntaxhighlight> '''输出:''' <pre> 1 4 9 16 25 1 4 9 16 25 </pre> == 高级主题:函数对象与模板 == 函数对象可以与模板结合,实现更灵活的代码。例如,通用比较器: <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> template <typename T> struct GreaterThan { T threshold; GreaterThan(T t) : threshold(t) {} bool operator()(T value) const { return value > threshold; } }; int main() { std::vector<int> nums = {1, 5, 3, 8, 2, 7}; GreaterThan<int> gt5(5); auto it = std::find_if(nums.begin(), nums.end(), gt5); if (it != nums.end()) { std::cout << "First number greater than 5: " << *it << std::endl; } return 0; } </syntaxhighlight> '''输出:''' <pre> First number greater than 5: 8 </pre> == 总结 == 函数对象是C++中强大的工具,它结合了面向对象编程和函数式编程的优点。通过重载<code>operator()</code>,函数对象可以像函数一样调用,同时保留状态和灵活性。它在标准库算法、回调机制和模板编程中广泛应用。 对于初学者,建议从简单的函数对象开始,逐步掌握其高级用法。对于高级用户,可以结合模板和Lambda表达式,编写更高效、更通用的代码。 [[Category:编程语言]] [[Category:C++]] [[Category:C++ 函数]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)