C 语言中的回调
回调是作为参数传递给另一个代码的任何可执行代码,该代码应在给定时间回调(执行)该参数。简单来说,如果一个函数的引用被传递给另一个函数作为调用它的参数,那么它将被称为回调函数。
在 C 语言中,回调函数是通过函数指针调用的函数。
下面是一个简单的 C 语言示例来说明上面的定义,以使其更加清晰。
// A simple C program to demonstrate callback
#include <stdio.h>
void A(){
printf("I am function A\n");
}
// callback function
void B(void (*ptr)())
{
(*ptr)(); // callback to A
}
int main()
{
void (*ptr)() = &A;
// calling function B and passing
// address of the function A as argument
B(ptr);
return 0;
}
输出
I am function A
在 C++ STL 中,函子也用于此目的。
C++ 中的函子
请注意,标题是函子(不是函数)!!
考虑一个只接受一个参数的函数。但是,在调用此函数时,我们有更多的信息要传递给该函数,但我们不能,因为它只接受一个参数。可以做些什么?
一个显而易见的答案可能是全局变量。然而,良好的编码实践并不提倡使用全局变量,并说只有在没有其他替代方法时才必须使用全局变量。
函子是可以被视为函数或函数指针的对象。函子最常与 STL 一起使用,方案如下:
下面的程序在 STL 中使用 transform() 将 1 添加到 arr[] 的所有元素中。
FP5系列
// A C++ program uses transform() in STL to add
// 1 to all elements of arr[]
#include <bits/stdc++.h>
using namespace std;
int increment(int x) { return (x+1); }
int main()
{
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr)/sizeof(arr[0]);
// Apply increment to all elements of
// arr[] and store the modified elements
// back in arr[]
transform(arr, arr+n, arr, increment);
for (int i=0; i<n; i++)
cout << arr[i] <<" ";
return 0;
}
输出:
2 3 4 5 6
时间复杂度:O(n)
空间复杂度:O(n),其中 n 是数组的大小。
此代码片段仅向 arr[] 的内容添加一个值。现在假设,我们想在 arr[] 的内容中添加 5。
看看发生了什么?由于变换需要数组的一元函数(仅接受一个参数的函数),因此我们不能将数字传递给 increment()。实际上,这将使我们编写几个不同的函数来添加每个数字。真是一团糟。这就是函子派上用场的地方。
函子(或函数对象)是一个 C++ 类,其作用类似于函数。使用相同的旧函数调用语法调用函子。为了创建一个函子,我们创建了一个重载 operator() 的对象。
The line,
MyFunctor(10);
Is same as
MyFunctor.operator()(10);
让我们更深入地研究并了解如何将其与 STL 结合使用。
FP5系列
// C++ program to demonstrate working of
// functors.
#include <bits/stdc++.h>
using namespace std;
// A Functor
class increment
{
private:
int num;
public:
increment(int n) : num(n) { }
// This operator overloading enables calling
// operator function () on objects of increment
int operator () (int arr_num) const {
return num + arr_num;
}
};
// Driver code
int main()
{
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr)/sizeof(arr[0]);
int to_add = 5;
transform(arr, arr+n, arr, increment(to_add));
for (int i=0; i<n; i++)
cout << arr[i] << " ";
}
输出:
6 7 8 9 10
时间复杂度:O(n)
空间复杂度:O(n),其中 n 是数组的大小。
因此,在这里,Increment 是一个函子,一个充当函数的 c++ 类。
The line,
transform(arr, arr+n, arr, increment(to_add));
is the same as writing below two lines,
// Creating object of increment
increment obj(to_add);
// Calling () on object
transform(arr, arr+n, arr, obj);
因此,创建了一个对象 a,该对象使 operator() 重载。因此,函子可以有效地与C++ STL结合使用。