【C++】回调函数
·
学习回调函数,回调函数是通过函数指针或对象调用的函数。
回调函数就是通过函数指针或对象调用的函数,只要能一个函数能够作为参数传入并调用,这个函数就是回调函数。
#include <iostream>
int addCallBack(int a,int b){//回调函数
std::cout <<a+b<<std::endl;
return 0;
}
int main(int argc, char** argv) {
int(*p)(int,int);
p = addCallBack;
p(1,2);
return 0;
}
为什么使用回调函数
前言里直接在main函数调用addCallBack不是更直接吗?为什么要使用函数指针接收addCallBack的地址,再调用呢?
回调函数,通常是为了实现“控制反转”(Inversion of Control), 灵活、分离、 异步与并发。
- 解耦和模块化: 函数与具体的逻辑解耦,可以复用。
// 排序算法(不关心具体比较逻辑)
void sort(int* arr, int n, bool(*compare)(int, int)) {
for (int i = 0; i < n-1; i++) { //解耦和模块化
for (int j = i+1; j < n; j++) {
if (compare(arr[i], arr[j])) {
std::swap(arr[i], arr[j]);
}
}
}
}
// 不同的比较策略
bool ascending(int a, int b) { return a > b; }
bool descending(int a, int b) { return a < b; }
int main() {
int data[] = {5, 2, 8, 1, 3};
sort(data, 5, ascending); // 升序
sort(data, 5, descending); // 降序
return 0;
}
- 异步处理:我不知道什么时候能算完
#include <thread>
#include <functional>
#include <iostream>
// 模拟异步任务
void asyncTask(std::function<void(int)> callback) {
std::thread([callback]() {
std::this_thread::sleep_for(std::chrono::seconds(2));
int result = 42; // 模拟计算结果
callback(result); // 完成后通过回调通知
}).detach();
}
// 回调处理结果
void handleResult(int result) {
std::cout << "异步任务完成,结果: " << result << std::endl;
}
int main() {
std::cout << "开始异步任务..." << std::endl;
asyncTask(handleResult); // 非阻塞调用
// 主线程可以继续做其他事情
for (int i = 0; i < 5; i++) {
std::cout << "主线程工作..." << i << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return 0;
}
实现
函数指针实现
普通函数调用
#include <iostream>
//回调函数 无参
void callBack(){
std::cout<<"无参回调函数"<<std::endl;
}
//回调函数 带参数
void callback_ii(int a,int b){
std::cout<<a+b<<std::endl;
}
//回调函数带返回值
int callback_return_i(){
int a = 10;
return a;
}
/*
定义函数指针
*/
//无参 函数指针
typedef void(*CallbackPtr)();
// 它是"指向返回void,接受两个int参数的函数"的指针类型
typedef void (*CallbackPtr_ii)(int, int);
// using CallbackPtr_using = void(*)(int, int);
//带返回值 函数指针
typedef int(*CallbackPtr_return_i)();
void performTask(CallbackPtr cb) {
cb(); // 执行回调
}
void performTask_ii(int a, int b, CallbackPtr_ii cb) {
// 业务逻辑...
cb(a, b); // 执行回调
}
void performTask_return_i(CallbackPtr_return_i cb) {
// 业务逻辑...
std::cout<< cb() <<std::endl;
}
int main(){
performTask(callBack);
performTask_ii(1,2,callback_ii);
performTask_return_i(callback_return_i);
return 0;
}
这里其实就是使用指针调用函数。
void (*p)(int ,int);
p = callback;
//p = &callback;
(*p)(0,1);
//p(0,1);
类成员函数和类静态函数调用
#include <iostream>
class MyClass {
public:
void Func(){
std::cout << "function" << std::endl;
}
static void staticFunc() {
std::cout << "Static function" << std::endl;
}
};
int main() {
void (*staticFuncPtr)() = &MyClass::staticFunc;
staticFuncPtr(); // 输出: Static function
/*
void (*funcPtr)() = &MyClass::Func;//error: cannot convert ‘void (MyClass::*)()’ to ‘void (*)()’ in initialization
funcPtr();
*/
// 指向普通成员函数 - 需要特殊的语法
MyClass MyObj;
void (MyClass::*FuncPtr)() = &MyClass::Func; // 声明成员函数指针
(MyObj.*FuncPtr)(); // 通过对象调用,输出: function
return 0;
}
Class A 调用 Class B
#include <iostream>
class ProgramA {
public:
void Func(void (*callback)()) {
std::cout << "A: callback" << std::endl;
callback();
}
};
class ProgramB {
public:
void Func() {
std::cout << "B: function" << std::endl;
}
static void staticFunc() {
std::cout << "B: Static function" << std::endl;
}
};
int main() {
ProgramA PA;
PA.Func(ProgramB::staticFunc);
return 0;
}
- 如何使用A调用B中的非静态方法?
这里只写两种方式。
方式一:使用function修改A的调用函数。
方式二:在A中修改参数
#include <iostream>
#include <functional>
class ProgramB;
class ProgramA {
public:
//方式一
void Func(std::function<void()> callback) {
std::cout << "A std::function<void(): callback" << std::endl;
callback();
}
//方式二
void Func(void(ProgramB::*callback)(),void *PBPtr){
std::cout << "A void(ProgramB::*callback)(): callback" << std::endl;
((ProgramB*)PBPtr->*callback)();//*不是解引用,而是指针到成员运算符 ->* 的一部
所有评论(0)