学习回调函数,回调函数是通过函数指针或对象调用的函数。

回调函数就是通过函数指针或对象调用的函数,只要能一个函数能够作为参数传入并调用,这个函数就是回调函数。

#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)();//*不是解引用,而是指针到成员运算符 ->* 的一部