回调函数CallBack的一些用法总结

回调函数CallBack的一些用法总结

回调函数callback

回调函数(Callback Function)是一种 通过函数指针或函数对象传递,并在特定事件发生时调用的函数。它用于 解耦逻辑,尤其适用于 事件驱动编程、异步操作、信号处理、线程池、多线程编程 等场景。

1. C语言方式

1.1 函数指针方式

在 C 语言中,回调函数通常是 通过函数指针传递,然后在需要的时候调用。

#include

// 定义回调函数类型

typedef void (*CallBack_name)(int, const char *str);

// 回调函数的实现

void myCallbackFunc(int value, const char *info) {

printf("回调函数被调用,值: %d, info: %s\n", value, info);

}

// 一个接受回调函数的函数

void processData(int data, CallBack_name callback) {

printf("处理数据: %d\n", data);

callback(data, "process done!"); // 触发回调

}

int main() {

processData(42, myCallbackFunc); // 传入回调函数

return 0;

}

这里解释一下typedef void (*CallBack_name)(int);的用法:

typedef void (*CallBack_name)(int, const char *str);

//是 C 语言 和 C++ 中 定义函数指针类型 的一种方式。它的作用是 定义一个新的类型 CallBack_name,该类型表示指向一个接受 int 参数并返回 void 的函数的指针。

// 1. void 表示函数的返回类型;

// 2. (*CallBack_name) 表示函数指针(CallBack_name 表示为函数指针的名称);

// 3. (int, const char *str) 表示函数的参数列表;

// 4. typedef 表示为这个复杂的类型起一个别名;相当于为函数指针: void (*CallBack_func)(int, const char *str); 起了一个别名CallBack_name,后续可以直接使用CallBack_name,就像使用普通类型那样。

// 若不使用typedef,则前面的代码与下面的代码等价:

#include

void myCallbackFunc(int value, const char *info) {

printf("回调函数被调用,值: %d, info: %s\n", value, info);

}

void processData(int data, void (*func)(int value, const char *info)) {

printf("处理数据: %d\n", data);

func(data, "process done!");

}

int main() {

processData(42, myCallbackFunc);

return 0;

}

// 这样写可读性比较差,所以 typedef 可以 简化 代码,使代码更清晰易读。

// 代码更清晰,减少了冗长的函数指针写法。

// 可以像使用普通类型一样使用函数指针。

// 在 struct 或 class 里更方便使用。

更丰富一些的用法:

#include

typedef int (*setInfoCB_t)(int, const char *);

int setInfoCbFunc(int age, const char *name) {

printf("callback: age: %d, name: %s\n", age, name);

return 10;

}

void processInfo(int age, setInfoCB_t callback) {

printf("get info: %d\n", age);

printf("callback ret = %d \n", callback(age * 2, "Rekko"));

}

int main() {

setInfoCB_t mInfoCb = NULL;

mInfoCb = setInfoCbFunc;

processInfo(12, mInfoCb);

return 0;

}

2. C++方式

2.1 函数指针方式

在 C++11 及以上版本,可以用 using 替代 typedef来声明函数指针,写法更加直观:

如:using setInfoCB_t = int (*)(int, const char *);

#include

using setInfoCB_t = int (*)(int, const char *);

int setInfoCbFunc(int age, const char *name) {

printf("callback: age: %d, name: %s\n", age, name);

return 10;

}

void processInfo(int age, setInfoCB_t callback) {

printf("get info: %d\n", age);

printf("callback ret = %d \n", callback(age * 2, "Rekko"));

}

int main() {

setInfoCB_t mInfoCb = nullptr;

mInfoCb = setInfoCbFunc;

processInfo(12, mInfoCb);

return 0;

}

2.2 std::function 方式

在 C++ 中,我们可以使用 std::function 作为回调函数的类型,它比传统的函数指针更灵活,可以接收 普通函数、Lambda 表达式、成员函数、仿函数等。

如:using setInfoCB_t = std::function;

#include

#include // 引入std::function

using setInfoCB_t = std::function;

int setInfoCbFunc(int age, const char *name) {

std::cout << "callback: age: " << age << ", name: " << name << std::endl;

return 10;

}

void processInfo(int age, setInfoCB_t callback) {

std::cout << "get info: " << age << std::endl;

int ret = callback(age * 2, "Rekko");

std::cout << "callback ret = " << ret << std::endl;

}

#if 0 // 普通函数

int main() {

setInfoCB_t mInfoCb = nullptr;

mInfoCb = setInfoCbFunc;

processInfo(12, mInfoCb);

return 0;

}

#endif

#if 1 // Lambda表达式

int main() {

processInfo(12, [](int age, const char *name) {

std::cout << "Lambda callback: age: " << age << ", name: " << name << std::endl;

return 1;

});

return 0;

}

// or

//int main() {

// setInfoCB_t mInfoCb = nullptr;

// mInfoCb = [](int age, const char *name) {

// std::cout << "Lambda callback: age: " << age << ", name: " << name << std::endl;

// return 1;

// };

//

// processInfo(12, mInfoCb);

// return 0;

//}

#endif

2.3 C++成员函数作为回调

C++ 成员函数不能直接作为普通回调函数传递,因为它们有一个 隐式的 this 指针,需要使用 std::bind 或 Lambda 转换。

示例:使用 std::bind 传递成员函数

#include

#include

class Processor {

public:

void memberCallback(int value) {

std::cout << "成员函数回调被调用,值: " << value << std::endl;

}

void run() {

// 绑定成员函数作为回调

processData(77, std::bind(&Processor::memberCallback, this, std::placeholders::_1));

}

private:

using Callback = std::function;

void processData(int data, Callback callback) {

std::cout << "处理数据: " << data << std::endl;

callback(data); // 调用回调

}

};

int main() {

Processor p;

p.run();

return 0;

}

2.4 C++仿函数(函数对象)作为回调

仿函数(Functors)是 重载 operator() 的类对象,可以像函数一样调用,并可以存储状态。

#include

#include

// 定义仿函数

class FunctorCallback {

public:

void operator()(int value) const {

std::cout << "仿函数回调被调用,值: " << value << std::endl;

}

};

// 处理数据并调用回调

void processData(int data, std::function callback) {

std::cout << "处理数据: " << data << std::endl;

callback(data);

}

int main() {

FunctorCallback functor;

processData(55, functor); // 传递仿函数作为回调

return 0;

}

总结

方式适用场景特点C 函数指针纯 C 代码、简单回调轻量级,但不支持成员函数std::functionC++ 回调函数更灵活,支持 Lambda、成员函数、仿函数成员函数回调面向对象编程需要 std::bind 或 Lambda 适配仿函数需要状态的回调可存储状态,复用性强Lambda一次性回调,简洁适用于小型回调函数回调函数是一种强大的编程技巧,在异步编程、事件驱动、网络编程、GUI 交互等场景中广泛应用。C++11 及更高版本中,std::function 和 std::bind 让回调更加灵活。

相关推荐

湖南社保多少钱一个月 2023湖南社保个人缴费标准一览表
温布利球场是谁的主场?在哪个城市?温布利球场在伦敦的位置
乒乓球混合团体世界杯赛程表!附12月8日cctv5乒乓直播表