C++ 函子

17 Mar 2025 | 6 分钟阅读

在 C++ 中,函数对象是一种函数对象——一个重载了函数调用运算符 () 的类的实例。函数对象用于提供一种面向对象的方式来处理函数或类函数对象。

函数对象可以在许多需要函数的情况下使用,包括 `std::transform()` 和 `std::sort()` 等算法以及映射和集合等自定义数据结构。

这是一个将参数乘以固定值的函数对象示例:

在这个示例中,Multiplier 是一个具有单个成员变量 `factor_` 的类,该变量在构造函数中设置。`operator()` 函数被重载以接受一个整数参数 x 并返回 `x * factor_`。

我们可以像这样使用这个函数对象:

在这个示例中,我们创建了一个 `Multiplier` 实例,其 `factor_` 值为 5。然后我们调用该函数对象,参数为 10,返回 `10 * 5 = 50`。

请注意,我们能够像调用常规函数一样调用 `multiply_by_5()`,但它是一个 `Multiplier` 类型的对象。这是因为 `operator()` 函数被重载,允许我们将对象作为函数调用。

函数对象通常与模板结合使用,以创建可与不同类型数据一起工作的灵活、可重用的代码。

函数对象相对于普通函数的必要性

函数对象在 C++ 中比普通函数具有许多优势。以下是一些您可能选择使用函数对象而不是普通函数的原因:

  1. 灵活性: 函数对象可以通过使用成员变量或构造函数参数进行定制,使其在不同情况下表现不同。这种灵活性是普通函数无法实现的。
  2. 封装: 函数对象可以封装与特定对象或类相关的行为。这可以使代码更有条理且更易于阅读。
  3. 多态性: 函数对象可以在需要函数指针或函数对象的情况下使用,从而实现多态性。这是普通函数无法实现的。
  4. 有状态行为: 函数对象可以在函数调用之间保持状态,从而记住有关先前调用的信息。普通函数无法实现这一点,因为它们在调用之间没有内存。
  5. 效率: 函数对象有时比普通函数更高效,因为它们可以避免调用单独函数的开销。在某些情况下,函数对象可以被编译器内联,从而进一步提高性能。

总之,函数对象提供了一种灵活而强大的方式来处理 C++ 中的函数或类函数对象。它们可以定制、封装、多态、有状态且高效。因此,它们是该语言中一种流行且广泛使用的特性。

C++ 函数对象的类型

C++ 中有三种类型的函数对象。

1. 生成器函数对象

在 C++ 中,生成器函数对象是一种函数对象,当重复调用时会生成一系列值。函数对象只是一个行为像函数的对象,即它可以被调用并带参数并返回一个值。

生成器函数对象通常实现为一个类,该类重载函数调用运算符 () 并在调用之间保持状态以生成一系列值。这是一个示例:

示例

输出

Functor in C++

说明

此程序创建一个 `FibonacciGenerator` 对象 `fib`,然后使用 for 循环通过重复调用生成器函数对象的 `operator()` 函数来生成前 20 个斐波那契数列。结果序列打印到控制台。

2. 一元函数对象

在 C++ 中,一元函数对象是一种函数对象,它接受一个特定类型的单个参数并返回另一种类型的值。函数对象只是一个行为像函数的对象,即它可以被调用并带参数并返回一个值。

一元函数对象通常实现为一个类,该类重载函数调用运算符 () 并接受一个特定类型的单个参数。

一元函数对象适用于各种应用程序,例如转换数据或将函数应用于值序列。它们可用于将特定操作或转换封装到可重用对象中,从而使代码更具模块化且更易于维护。

这是一个完整的程序,演示如何使用 `Square` 一元函数对象计算整数序列的平方:

示例

输出

Functor in C++

说明

此程序创建一个 `Square` 一元函数对象 `square`,并使用 for 循环调用该函数对象的 `operator()` 函数并带一个整数序列。结果序列的平方打印到控制台。

请注意,在此程序中,我们将 `Square` 函数对象的 `operator()` 函数标记为 `const`,以表明它不修改函数对象的状态。这是定义函数对象时的良好实践,因为它清楚地表明函数对象是无状态的且没有任何副作用。

3. 二元函数对象

在 C++ 中,二元函数对象是一种函数对象,它接受两个特定类型的参数并返回另一种类型的值。函数对象只是一个行为像函数的对象,即它可以被调用并带参数并返回一个值。

二元函数对象通常实现为一个类,该类重载函数调用运算符 () 并接受两个特定类型的参数。

此二元函数对象接受两个参数 x 和 y,两者均为 int 类型,并返回它们的和。`operator()` 函数标记为 `const`,以表明它不修改函数对象的状态。

这是一个完整的程序,演示如何使用 `Add` 二元函数对象计算两个整数的和:

示例

输出

Functor in C++

说明

此程序创建一个 `Add` 二元函数对象 `add`,并调用该函数对象的 `operator()` 函数并带两个整数参数。结果和被赋值给 `result` 变量并打印到控制台。

请注意,在此程序中,我们将 `Add` 函数对象的 `operator()` 函数标记为 `const`,以表明它不修改函数对象的状态。这是定义函数对象时的良好实践,因为它清楚地表明函数对象是无状态的且没有任何副作用。

如何创建 C++ 函数对象?

我们可以轻松地在 C++ 中创建函数对象;为此,我们必须首先创建一个类,然后我们必须重载函数调用运算符 (),之后我们可以创建该特定类的实例或对象并将其作为函数调用。

让我们通过一个示例来理解这一点:

示例

输出

Functor in C++
下一个主题C++ GUI