
回调函数到底是个啥
Admin·5/30/2025·0 views
C++编程概念
回调函数
什么是回调函数?
回调函数(Callback Function)就是你把一个函数“传递”给另一个函数,当某个事件发生时,这个函数会被“回调”执行。 举例:
void onDataReceived(int data) {
// 处理收到的数据
}
void asyncRead(void(*callback)(int)) {
// ... 异步读取数据
// 数据到来时
callback(data); // 调用回调函数
}
回调的最大作用:解耦和灵活
直接调用A的缺点
- 如果B里直接写死调用A,那么B只能做一种固定的事情,扩展性很差。
- 如果以后想让B调用别的函数(比如A1、A2、A3),就得改B的代码,维护成本高。 用回调的好处
- B不关心A具体做什么,只负责“在合适的时候调用你给我的函数”。
- 你可以把不同的函数传给B,B就能做不同的事情,B的代码不用改。
- 这样B就变成了一个“通用工具”,而A是“定制化逻辑”。
现实类比
- 你去饭店点菜(B),你告诉厨师(B)你要什么菜(A),厨师只管做你点的菜。
- 如果你每次都要厨师做同一道菜,那厨师的工作就很死板。
- 如果你可以告诉厨师不同的菜名,厨师就能灵活应对不同需求。
代码场景举例
没有回调(写死逻辑)
void B() {
// 只能做A的事情
A();
}
有回调(灵活扩展)
void B(void(*callback)()) {
// 只负责在合适的时候调用callback
callback();
}
void A1() { /* ... */ }
void A2() { /* ... */ }
int main() {
B(A1); // 让B做A1的事
B(A2); // 让B做A2的事
}
- 这样B就能适应不同的需求,A1、A2可以随时换,B不用改。
典型应用场景
-
排序时的比较函数(你可以自定义升序、降序、按长度等)
-
遍历容器时的处理逻辑(你可以自定义每个元素怎么处理)
-
异步IO、事件驱动(你可以自定义事件发生时的处理方式)
总结
-
回调让B变成“通用工具”,A变成“定制逻辑”,两者解耦,代码更灵活、可扩展、可复用。
-
如果B里写死A,扩展性和灵活性就没了。
复杂的回调设计模式
策略模式
概念:
- 策略模式就是把一组算法(或行为)封装成独立的“策略类”,在运行时可以互相替换。
- 这样,使用者(Context)不用关心具体用哪种算法,只需要“注入”一个策略对象即可。
和回调的关系
- 策略模式本质上就是“把行为(函数/对象)交给别人”,别人(Context)在合适的时候调用,这就是一种回调思想。
// 策略接口
class SortStrategy {
public:
virtual void sort(std::vector<int>& data) = 0;
virtual ~SortStrategy() = default;
};
// 具体策略A
class BubbleSort : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
// 冒泡排序实现
}
};
// 具体策略B
class QuickSort : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
// 快速排序实现
}
};
// 上下文
class Context {
SortStrategy* strategy;
public:
Context(SortStrategy* s) : strategy(s) {}
void setStrategy(SortStrategy* s) { strategy = s; }
void doSort(std::vector<int>& data) { strategy->sort(data); }
};
int main() {
std::vector<int> data = {3, 1, 4, 2};
BubbleSort bubble;
QuickSort quick;
Context ctx(&bubble);
ctx.doSort(data); // 用冒泡
ctx.setStrategy(&quick);
ctx.doSort(data); // 换成快速
}
- 这里Context并不关心用什么排序算法,具体算法由外部注入,这就是“回调思想”的面向对象实现。
观察者模式
概念:
- 观察者模式是一种“发布-订阅”机制。
- 一个主题(Subject)可以有多个观察者(Observer),当主题状态变化时,会自动通知所有观察者。
和回调的关系
- 观察者注册自己的“回调函数”到主题,主题在事件发生时自动调用这些回调。
现实举例 公众号订阅,通知所有人
代码举例
#include <vector>
#include <iostream>
// Observer 观察者接口
class Observer {
public:
// 所有 观察这都要实现update方法
virtual void update(int value) = 0;
};
class Subject {
// 存储所有的观察者
std::vector<Observer*> observers;
int state = 0;
public:
void attach(Observer* obs) { observers.push_back(obs); }
void setState(int value) {
state = value;
for (auto obs : observers) {
// 每个观察者都调用自己的update方法,更加灵活
obs->update(state); // 通知所有观察者
}
}
};
class ConcreteObserver : public Observer {
public:
void update(int value) override {
std::cout << "收到通知,状态变为: " << value << std::endl;
}
};
int main() {
Subject subject;
ConcreteObserver obs1, obs2;
subject.attach(&obs1);
subject.attach(&obs2);
subject.setState(42); // 所有观察者都会收到通知
}