在C++中,回调函数是一种通过函数指针或其他方式来传递和调用函数的机制。回调函数允许一个函数在执行到某个特定时刻时,调用另一段代码。以下是关于C++回调函数的详细说明,包括应用方式和使用场景
回调函数的实现方式
1、 函数指针
函数指针是指向函数的指针,可以用来调用该函数。
// 定义一个函数指针类型
typedef void (*CallbackFunc)();
// 一个示例函数
void MyFunction() {
std::cout << "MyFunction called!" << std::endl;
}
// 一个接受回调函数的函数
void RegisterCallback(CallbackFunc callback) {
// 调用回调函数
callback();
}
int main() {
// 注册并调用回调函数
RegisterCallback(MyFunction);
return 0;
}
2、模板和仿函数
使用模板和仿函数(即重载了operator()的类)也可以实现回调。
// 定义仿函数类
class MyCallback {
public:
void operator()() const {
std::cout << "MyCallback called!" << std::endl;
}
};
// 一个接受回调的模板函数
template <typename Callback>
void RegisterCallback(Callback callback) {
callback();
}
int main() {
MyCallback myCallback;
RegisterCallback(myCallback);
return 0;
}
3、std::function 和 std::bind
std::function 是一个通用的函数封装器,可以持有任意可调用对象,包括函数指针、Lambda表达式、仿函数等。
#include <iostream>
#include <functional>
void MyFunction() {
std::cout << "MyFunction called!" << std::endl;
}
void RegisterCallback(std::function<void()> callback) {
callback();
}
int main() {
// 使用函数指针
RegisterCallback(MyFunction);
// 使用Lambda表达式
RegisterCallback([]() {
std::cout << "Lambda called!" << std::endl;
});
return 0;
}
使用场景
1、事件驱动编程
在GUI应用或游戏开发中,经常需要处理用户事件(如按钮点击、鼠标移动等)。回调函数用于处理这些事件
使用模板和仿函数(即重载了operator()的类)也可以实现回调。
// 伪代码示例
class Button {
public:
void setOnClickCallback(std::function<void()> callback) {
onClickCallback = callback;
}
void click() {
if (onClickCallback) {
onClickCallback();
}
}
private:
std::function<void()> onClickCallback;
};
int main() {
Button button;
button.setOnClickCallback([]() {
std::cout << "Button clicked!" << std::endl;
});
button.click();
return 0;
}
2、异步编程
回调函数常用于异步操作中,如网络请求完成后的处理、文件读写完成后的处理等。
#include <thread>
#include <functional>
void asyncOperation(std::function<void(int)> callback) {
// 模拟耗时操作
std::this_thread::sleep_for(std::chrono::seconds(2));
callback(42); // 回调传递结果
}
int main() {
std::cout << "Starting async operation..." << std::endl;
asyncOperation([](int result) {
std::cout << "Async operation completed with result: " << result << std::endl;
});
std::cout << "Doing other work..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3)); // 等待异步操作完成
return 0;
}
3、策略模式
使用回调函数可以实现策略模式,在运行时选择不同的算法或行为。
class Context {
public:
void setStrategy(std::function<void()> strategy) {
this->strategy = strategy;
}
void executeStrategy() {
strategy();
}
private:
std::function<void()> strategy;
};
void strategyA() {
std::cout << "Strategy A executed." << std::endl;
}
void strategyB() {
std::cout << "Strategy B executed." << std::endl;
}
int main() {
Context context;
context.setStrategy(strategyA);
context.executeStrategy();
context.setStrategy(strategyB);
context.executeStrategy();
return 0;
}