目录

函数指针是指向函数的指针变量。
通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
函数指针可以像一般函数一样,用于调用函数、传递参数。
函数指针类型的声明:
typedef type (*fun_ptr)(type,type); // 声明一个指向同样参数、返回值的函数指针类型
以下实例声明了函数指针变量 p,指向函数 max:
- #include
- #define _CRT_SECURE_NO_WARNINGS
- typedef int(*func_ptr)(int, int);
-
- int max(int x, int y)
- {
- return x > y ? x : y;
- }
-
- int main(void)
- {
- //p是指向max的函数指针
- func_ptr p = &max;//也可以写成 func_ptr p = max;
-
- int a, b, c, d;
-
- printf("请输入三个数字:");
- scanf("%d %d %d", &a, &b, &c);
-
- /* 与直接调用函数等价,d = max(max(a, b), c) */
- d = p(p(a, b), c);
-
- printf("最大的数字是: %d\n", d);
-
- return 0;
- }

函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。
简单讲:回调函数是由别人的函数执行时调用你实现的函数。
以下是来自知乎作者常溪玲的解说:
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
实例中 populate_array() 函数定义了三个参数,其中第三个参数是函数的指针,通过该函数来设置数组的值。
实例中我们定义了回调函数 getNextRandomValue(),它返回一个随机值,它作为一个函数指针传递给 populate_array() 函数。
populate_array() 将调用 10 次回调函数,并将回调函数的返回值赋值给数组。
-
- #include
- #include
-
- void populate_array(int* array, size_t arraySize, int (*getNextValue)(void))
- {
- for (size_t i = 0; i < arraySize; i++)
- array[i] = getNextValue();
- }
-
- // 获取随机值
- int getNextRandomValue(void)
- {
- return rand();
- }
-
- int main(void)
- {
- int myarray[10];
-
- populate_array(myarray, 10, getNextRandomValue);//函数的名称就是函数的地址
- for (int i = 0; i < 10; i++) {
- printf("%d ", myarray[i]);
- }
- printf("\n");
- return 0;
- }

- #include
- #include
-
- struct Foo
- {
- Foo(int num) : num_(num) {}
- void print_add(int i) const { std::cout << num_ + i << '\n'; }
- int num_;
- };
-
- void print_num(int i)
- {
- std::cout << i << '\n';
- }
-
- struct PrintNum
- {
- void operator()(int i) const
- {
- std::cout << i << '\n';
- }
- };
-
- int main()
- {
- // store a free function
- std::function<void(int)> f_display = print_num;
- f_display(-9);
-
- // store a lambda
- std::function<void()> f_display_42 = []() { print_num(42); };
- f_display_42();
-
- // store the result of a call to std::bind
- std::function<void()> f_display_31337 = std::bind(print_num, 31337);
- f_display_31337();
-
- // store a call to a member function
- std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
- const Foo foo(314159);
- f_add_display(foo, 1);
- f_add_display(314159, 1);
-
- // store a call to a data member accessor
- std::function<int(Foo const&)> f_num = &Foo::num_;
- std::cout << "num_: " << f_num(foo) << '\n';
-
- // store a call to a member function and object
- using std::placeholders::_1;
- std::function<void(int)> f_add_display2 = std::bind(&Foo::print_add, foo, _1);
- f_add_display2(2);
-
- // store a call to a member function and object ptr
- std::function<void(int)> f_add_display3 = std::bind(&Foo::print_add, &foo, _1);
- f_add_display3(3);
-
- // store a call to a function object
- std::function<void(int)> f_display_obj = PrintNum();
- f_display_obj(18);
-
- auto factorial = [](int n)
- {
- // store a lambda object to emulate "recursive lambda"; aware of extra overhead
- std::function<int(int)> fac = [&](int n) { return (n < 2) ? 1 : n * fac(n - 1); };
- // note that "auto fac = [&](int n) {...};" does not work in recursive calls
- return fac(n);
- };
- for (int i{5}; i != 8; ++i)
- std::cout << i << "! = " << factorial(i) << "; ";
- std::cout << '\n';
- }

- #include
- #include
-
- //普通函数
- void func(void)
- {
- std::cout << __FUNCTION__ << std::endl;
- }
- //静态类成员函数
- class Foo
- {
- public:
- static int foo_func(int a)
- {
- std::cout << __FUNCTION__ << "(" << a << ") ->:";
- return a;
- }
- };
-
-
- int main(void)
- {
- std::function<void(void)> fr = func;
- fr();
- std::function<int(int)> fr1 = Foo::foo_func;
- std::cout << fr1(456) << std::endl;
- }

- #include
- #include
- class A
- {
- std::function<void()> callback_;
- public:
- A(const std::function<void()>& f) :callback_(f) {};
- void notify(void)
- {
- callback_();
- }
- };
- class Foo {
- public:
- void operator()(void)
- {
- std::cout << __FUNCTION__ << std::endl;
- }
- };
- int main(void)
- {
- Foo foo;
- A aa(foo);
- aa.notify();
- }
- #include
- #include
- void call_when_even(int x, const std::function<void(int)>& f)
- {
- if (!(x & 1))
- {
- f(x);
- }
- }
- void output(int x)
- {
- std::cout << x << " ";
- }
- int main(void)
- {
- for (int i = 0; i < 10; ++i)
- {
- call_when_even(i, output);
- }
- std::cout << std::endl;
- }
`std::function`是C++标准库中的一个通用、可调用、多态的函数封装器,可以用来存储任何可调用对象的引用,如函数指针、函数对象、Lambda表达式等。它的主要作用是将函数作为参数传递,实现回调函数的功能。
下面是一个简单的实例,演示了如何使用`std::function`存储一个函数,并调用它:`
在这个例子中,我们定义了
- #include
- #include
-
- void print_hello() {
- std::cout << "Hello, world!" << std::endl;
- }
-
- int main() {
- std::function<void()> func = print_hello;
- func();
- return 0;
- }
一个名为`print_hello`的函数,用于打印"Hello, world!"。然后,我们创建了一个`std::function
在C++中,`std::function`是一个通用、可调用、多态的函数封装器,可以用来存储任何可调用对象的引用,如函数指针、函数对象、Lambda表达式等。`std::function`的模板参数`T`表示存储的函数的参数类型,当`T`是一个函数指针类型时,`std::function`可以用来存储一个函数指针;当`T`是一个函数对象类型时,`std::function`可以用来存储一个函数对象;当`T`是一个Lambda表达式类型时,`std::function`可以用来存储一个Lambda表达式。
下面是一些例子:
- // 存储一个接受两个int参数的函数
- std::function<int(int, int)> func1;
-
- // 存储一个接受一个int参数并返回一个int的函数
- std::function<int(int)> func2;
-
- // 存储一个不接受任何参数的函数
- std::function<void()> func3;
-
- // 存储一个Lambda表达式
- std::function<int(int)> func4 = [](int x) { return x * 2; };
在这些例子中,`func1`和`func2`可以用来存储任何接受相应参数类型的函数,`func3`可以用来存储任何不接受任何参数的函数,`func4`可以用来存储一个接受一个int参数并返回一个int的Lambda表达式。
- #include
- #include
-
- class A {
- public:
- A(const std::function<void()>& f) :callback_(f) {};
-
- void print() {
- callback_();
- }
-
- private:
- std::function<void()> callback_;
- };
-
- int main() {
- A obj([&]() {
- std::cout << "Hello, World!" << std::endl;
- });
-
- obj.print();
-
- return 0;
- }
在这个例子中,我们定义了一个名为A的类,它有一个构造函数,接受一个名为callback_的std::function