回调函数的概念

回调函数的基本概念

回调函数的本质是"你定义,我调用" - 你提供一个函数,系统或框架在特定时机调用它。

实现回调函数的几种方式

1. 函数指针(传统方式)

复制代码
#include <iostream>

// 回调函数类型定义
typedef void (*Callback)(int, const std::string&);

// 接受回调函数的函数
void processData(int value, const std::string& name, Callback callback) {
    std::cout << "处理数据中..." << std::endl;
    // 处理完成后调用回调函数
    callback(value, name);
}

// 具体的回调函数实现
void myCallback(int num, const std::string& text) {
    std::cout << "回调函数被调用: " << num << ", " << text << std::endl;
}

int main() {
    processData(42, "Hello", myCallback);
    return 0;
}

2. std::function(现代方式)

复制代码
#include <iostream>
#include <functional>

void processData(int value, const std::string& name, 
                std::function<void(int, const std::string&)> callback) {
    std::cout << "处理数据中..." << std::endl;
    callback(value, name);
}

void myCallback(int num, const std::string& text) {
    std::cout << "回调函数被调用: " << num << ", " << text << std::endl;
}

int main() {
    // 使用函数指针
    processData(42, "World", myCallback);
    
    // 使用lambda表达式
    processData(100, "Lambda", [](int n, const std::string& s) {
        std::cout << "Lambda回调: " << n << ", " << s << std::endl;
    });
    
    return 0;
}

3. 函数对象(Functor)

复制代码
#include <iostream>

class MyCallback {
public:
    void operator()(int value, const std::string& message) {
        std::cout << "函数对象回调: " << value << ", " << message << std::endl;
    }
};

template<typename CallbackType>
void processData(int value, const std::string& name, CallbackType callback) {
    std::cout << "处理数据中..." << std::endl;
    callback(value, name);
}

int main() {
    MyCallback callbackObj;
    processData(200, "Functor", callbackObj);
    return 0;
}

实际应用示例

事件处理系统

复制代码
#include <iostream>
#include <functional>
#include <vector>

class Button {
private:
    std::vector<std::function<void()>> clickCallbacks;

public:
    // 注册点击回调
    void onClick(std::function<void()> callback) {
        clickCallbacks.push_back(callback);
    }
    
    // 模拟按钮点击
    void click() {
        std::cout << "按钮被点击!" << std::endl;
        for (auto& callback : clickCallbacks) {
            callback();
        }
    }
};

int main() {
    Button btn;
    
    // 注册多个回调函数
    btn.onClick([]() {
        std::cout << "执行操作1: 保存文件" << std::endl;
    });
    
    btn.onClick([]() {
        std::cout << "执行操作2: 更新界面" << std::endl;
    });
    
    // 模拟点击
    btn.click();
    
    return 0;
}

异步操作回调

复制代码
#include <iostream>
#include <functional>
#include <thread>
#include <chrono>

void asyncOperation(std::function<void(bool, const std::string&)> callback) {
    std::thread([callback]() {
        std::cout << "开始异步操作..." << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        
        // 模拟操作完成
        bool success = true; // 或 false
        std::string result = "操作完成";
        
        callback(success, result);
    }).detach();
}

int main() {
    std::cout << "主线程继续执行..." << std::endl;
    
    asyncOperation([](bool success, const std::string& message) {
        if (success) {
            std::cout << "成功: " << message << std::endl;
        } else {
            std::cout << "失败: " << message << std::endl;
        }
    });
    
    // 等待异步操作完成
    std::this_thread::sleep_for(std::chrono::seconds(3));
    return 0;
}

回调函数的优点

  1. 灵活性: 可以在运行时决定执行什么代码

  2. 解耦合: 将调用者和被调用者分离

  3. 可扩展性: 容易添加新的回调函数

  4. 异步支持: 非常适合异步编程模式

注意事项

  • 使用 std::function 比原始函数指针更安全灵活

  • 注意回调函数的生命周期管理

  • 在多线程环境中要注意线程安全问题

  • 避免过深的回调嵌套(回调地狱)

回调函数是C++中实现事件驱动编程和异步编程的重要工具,在现代C++开发中广泛应用。

相关推荐
geovindu2 分钟前
rust:Builder Pattern
开发语言·设计模式·rust·建造者模式
半生过往7 分钟前
前端工程师学习智能体开发(一)
前端·学习·状态模式
白远山10 分钟前
健身场馆无人自动化解决方案:从架构到落地实践
java·开发语言·数据库·数据挖掘·需求分析
白雾茫茫丶12 分钟前
Vibecoding 一个主题切换动画库:13 种揭幕方式
前端·vue.js·react.js
计算机魔术师23 分钟前
谷歌宣布 TPU 互联架构支持 100 万芯片规模,电力供应成 AI 基建核心瓶颈
前端
雪芽蓝域zzs27 分钟前
第四十九节:TagsView 右键菜单(带三角箭头)给每个 tag 增加**鼠标右键菜单**(右键标签弹出:关闭、关闭其他、关闭全部)
前端·javascript·vue.js
এ慕ོ冬℘゜41 分钟前
从零开发移动端医院挂号页面:适配、交互与前端实现详解
前端·javascript
宁渡AI大模型1 小时前
AI 全栈面试新趋势:Vibe Coding、前端、Java 后端高频面试题深度解析|河南宁渡科技有限公司编程教程
java·javascript·人工智能·python·ai大模型
Data_Journal1 小时前
如何将网页抓取用于机器学习
大数据·开发语言·数据库·python·scrapy
东风微鸣1 小时前
AI依赖更新别裸奔🚨
javascript