📅  最后修改于: 2023-12-03 14:39:54.849000             🧑  作者: Mango
在 C++ 中,函数也可以被传递作为参数给另一个函数使用。这种技术被称为函数指针或者函数对象。
函数指针是一个指向函数的指针变量。当一个函数的地址被赋给一个指针变量时,该指针变量便成为了一个函数指针。
以下是一个简单的例子:
#include <iostream>
void print(int i) {
std::cout << i << std::endl;
}
void useFunctionPointer(void (*pointer)(int)) {
for (int i = 0; i < 5; ++i) {
pointer(i);
}
}
int main() {
useFunctionPointer(print);
return 0;
}
代码解读:
print
接受一个整数参数,打印该数字到标准输出。useFunctionPointer
函数接受一个函数指针作为参数,这个函数指针指向与 print
相同的函数签名(即 void function(int)
)。useFunctionPointer
函数循环 0 到 4,调用传进去的函数指针,并传递当前循环变量作为实参。main
函数内,我们使用 useFunctionPointer
(将函数 print
传递给它) 反复地调用 print
函数。如果您还不熟悉 C++ 中的面向对象编程,则建议先学习一下。在此处,我们主要关注重载函数调用运算符(即 operator()
)的类的使用,通常被称为函数对象。
以下是一个简单的例子:
#include <iostream>
class Test
{
public:
void operator() (int i) const {
std::cout << i << std::endl;
}
};
void useFunctionObject(const Test& t) {
for (int i = 0; i < 5; ++i) {
t(i);
}
}
int main() {
Test test;
useFunctionObject(test);
return 0;
}
代码解读:
Test
的类,其中有一个单独的成员函数 operator()
operator()
函数其实是一个函数调用运算符,用于将一个类的实例(也就是对象)作为函数来调用。当使用这个运算符时,会先创建一个匿名对象并调用其 operator()
函数。useFunctionObject
函数接受一个 const Test&
类型参数,这个参数是一个 const
引用,用于指向 Test
类型的一个常量对象。useFunctionObject
函数内,我们使用接收到的参数来实例化一个 Test
对象,然后循环调用它的 operator()
函数。Lambda 表达式是一个把函数对象作为参数传递的更便捷的方法。它们从 C++11 开始被引入,并且常用于算法和 STL 中。
以下是一个简单的例子:
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
std::for_each(v.begin(), v.end(), [](int i) {
std::cout << i << std::endl;
});
return 0;
}
代码解读:
std::for_each
函数是 STL 中的一个算法,用于接受一个函数对象并用它来迭代实参范围中的每个元素。std::for_each
的第三个参数,这个 lambda 表达式输出了迭代到的整数到标准输出。以上是使用函数作为参数的三种方法。其中,函数指针和函数对象都是在采用“函数作为参数”时的用于传递函数的方式。而 Lambda 则是一种更加简便的方式,如果您的编译器支持 C++11,我们强烈建议优先使用 Lambda 表达式。