『 C++ 』中理解回调类型在 C++ 中的使用方式。
文章目录
- 案例 1:图形绘制库中的回调使用
- 场景说明
- 代码实现
- 代码解释
- 案例 2:网络服务器中的连接和消息处理回调
- 场景说明
- 代码实现
- 代码解释
- 案例 3:定时器中的回调使用
- 场景说明
- 代码实现
- 代码解释
以下将通过不同场景给出几个使用回调类型的具体案例,帮助你理解回调类型在 C++ 中的使用方式。
我在这里掉进一个坑,一直以为调用回调函数时,是在调用回调fction构造回调类型函数类型,就一直在下为什么他在这里只传入了类的指针(虽然类有成员方法,但是它知道调用哪个吗?)。后面发现在main函数调用回调函数时,才发现这里传入的是类外面,重新创建的回调函数。(可以不用看😂)
这里的声明的类型例如:using DrawCompleteCallback = std::function<void()>; ,它仅仅只是一个类型,方便类中方法的参数定义,后面定义的回调函数才是真正作为回调函数要调用,并且可以使用回调类型的方法。
案例 1:图形绘制库中的回调使用
场景说明
假设你正在开发一个简单的图形绘制库,当图形绘制完成后,需要通知调用者执行一些额外操作,比如记录日志或者更新界面状态。这时就可以使用回调函数来实现这种通知机制。
代码实现
#include <iostream>
#include <functional>
// 定义绘制完成的回调类型
using DrawCompleteCallback = std::function<void()>;
// 图形类
class Shape {
public:
void draw(DrawCompleteCallback callback) {
std::cout << "Drawing the shape..." << std::endl;
// 模拟绘制过程
for (int i = 0; i < 1000000; ++i) {}
std::cout << "Shape drawn." << std::endl;
// 绘制完成后调用回调函数
if (callback) {
callback();
}
}
};
// 日志记录函数,作为回调函数
void logDrawCompletion() {
std::cout << "Logging: Shape drawing is completed." << std::endl;
}
int main() {
Shape shape;
// 使用日志记录函数作为回调
shape.draw(logDrawCompletion);
return 0;
}
代码解释
- 回调类型定义:
DrawCompleteCallback
是一个不接受任何参数且返回值为void
的可调用对象类型。 Shape
类:draw
方法接受一个DrawCompleteCallback
类型的参数,在图形绘制完成后调用该回调函数。- 回调函数实现:
logDrawCompletion
是一个普通函数,作为回调函数用于记录图形绘制完成的日志。 - 主函数调用:在
main
函数中,创建Shape
对象并调用draw
方法,传入logDrawCompletion
作为回调函数。
案例 2:网络服务器中的连接和消息处理回调
场景说明
在一个简单的网络服务器中,需要处理新连接的建立、连接关闭以及接收到消息等事件。可以使用回调函数来处理这些事件。
代码实现
#include <iostream>
#include <memory>
#include <functional>
// 假设的连接类和消息类
class BaseMessage {
public:
using ptr = std::shared_ptr<BaseMessage>;
};
class BaseConnection {
public:
using ptr = std::shared_ptr<BaseConnection>;
};
// 定义回调类型
using ConnectionCallback = std::function<void(const BaseConnection::ptr&)>;
using CloseCallback = std::function<void(const BaseConnection::ptr&)>;
using MessageCallback = std::function<void(const BaseConnection::ptr&, BaseMessage::ptr&)>;
// 服务器类
class Server {
public:
void setConnectionCallback(const ConnectionCallback& cb) {
connectionCallback = cb;
}
void setCloseCallback(const CloseCallback& cb) {
closeCallback = cb;
}
void setMessageCallback(const MessageCallback& cb) {
messageCallback = cb;
}
// 模拟新连接事件
void simulateNewConnection() {
BaseConnection::ptr conn = std::make_shared<BaseConnection>();
if (connectionCallback) {
connectionCallback(conn);
}
}
// 模拟连接关闭事件
void simulateConnectionClose() {
BaseConnection::ptr conn = std::make_shared<BaseConnection>();
if (closeCallback) {
closeCallback(conn);
}
}
// 模拟接收到消息事件
void simulateMessageReceived() {
BaseConnection::ptr conn = std::make_shared<BaseConnection>();
BaseMessage::ptr msg = std::make_shared<BaseMessage>();
if (messageCallback) {
messageCallback(conn, msg);
}
}
private:
ConnectionCallback connectionCallback;
CloseCallback closeCallback;
MessageCallback messageCallback;
};
// 处理新连接的回调函数
void handleNewConnection(const BaseConnection::ptr& conn) {
std::cout << "New connection established." << std::endl;
}
// 处理连接关闭的回调函数
void handleConnectionClose(const BaseConnection::ptr& conn) {
std::cout << "Connection closed." << std::endl;
}
// 处理接收到消息的回调函数
void handleMessageReceived(const BaseConnection::ptr& conn, BaseMessage::ptr& msg) {
std::cout << "Message received on connection." << std::endl;
}
int main() {
Server server;
// 设置回调函数
server.setConnectionCallback(handleNewConnection);
server.setCloseCallback(handleConnectionClose);
server.setMessageCallback(handleMessageReceived);
// 模拟事件
server.simulateNewConnection();
server.simulateMessageReceived();
server.simulateConnectionClose();
return 0;
}
代码解释
- 回调类型定义:定义了
ConnectionCallback
、CloseCallback
和MessageCallback
三种回调类型,分别用于处理新连接建立、连接关闭和接收到消息事件。 Server
类:提供了设置回调函数的方法,并模拟了三种事件的发生,在事件发生时调用相应的回调函数。- 回调函数实现:分别实现了处理新连接、连接关闭和接收到消息的回调函数。
- 主函数调用:在
main
函数中,创建Server
对象,设置回调函数,并模拟三种事件的发生。
案例 3:定时器中的回调使用
场景说明
实现一个简单的定时器类,当定时器超时后,执行指定的回调函数。
代码实现
#include <iostream>
#include <functional>
#include <thread>
#include <chrono>
// 定义定时器回调类型
using TimerCallback = std::function<void()>;
// 定时器类
class Timer {
public:
void start(int seconds, TimerCallback callback) {
std::thread([seconds, callback]() {
std::this_thread::sleep_for(std::chrono::seconds(seconds));
if (callback) {
callback();
}
}).detach();
}
};
// 定时器超时后的回调函数
void onTimerExpired() {
std::cout << "Timer expired!" << std::endl;
}
int main() {
Timer timer;
// 启动定时器,设置超时时间为 3 秒,并传入回调函数
timer.start(3, onTimerExpired);
std::cout << "Timer started. Waiting for expiration..." << std::endl;
// 为了避免主线程提前退出,让主线程休眠一段时间
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}
代码解释
- 回调类型定义:
TimerCallback
是一个不接受任何参数且返回值为void
的可调用对象类型。 Timer
类:start
方法接受一个超时时间(秒)和一个TimerCallback
类型的回调函数,启动一个新线程,在指定的超时时间后调用回调函数。- 回调函数实现:
onTimerExpired
是一个普通函数,作为定时器超时后的回调函数,输出提示信息。 - 主函数调用:在
main
函数中,创建Timer
对象,启动定时器并传入onTimerExpired
作为回调函数。
通过以上案例,你可以看到回调类型在不同场景下的使用方式,其核心思想是将一个可调用对象作为参数传递给某个函数或类,在特定事件发生时调用该可调用对象。