当前位置: 首页 > news >正文

C++ 回调函数

一、简单理解

函数指针 

#include <iostream>
#include <string>void Server(std::string translation)
{std::cout << "I am a Server ,The words that the client needs to translate -> " << translation <<" <-> 苹果" << std::endl;
}
// 实现一个英文翻译 --> 这里先不这么复杂
// 客户端发来 apple
void Client(std::string word, void(*callback)(std::string))
{std::cout << "I am a client this English is: " << word << std::endl;callback(word);
}int main()
{Client("apple", Server);return 0;
}

 function


using func_t = std::function<void(std::string)>;void Server(std::string translation)
{std::cout << "I am a Server ,The words that the client needs to translate -> " << translation <<" <-> 苹果" << std::endl;
}void Client(std::string word, func_t callback)
{std::cout << "I am a client this English is: " << word << std::endl;callback(word);
}int main()
{Client("apple", Server);return 0;
}

Lambda 

using func_t = std::function<void(std::string)>;void Client(std::string word, func_t callback)
{std::cout << "I am a client this English is: " << word << std::endl;callback(word);
}
int main()
{Client("apple", [](std::string word) {std::cout << "I am a Server ,The words that the client needs to translate -> " << word << " <-> 苹果" << std::endl;});return 0;
}

仿函数 

class Server
{
public:void operator()(std::string translation){std::cout << "I am a Server ,The words that the client needs to translate -> " << translation << " <-> 苹果" << std::endl;}
};void Client(std::string word, Server server)
{std::cout << "I am a client this English is: " << word << std::endl;server(word);
}int main()
{Server server;Client("apple", server);return 0;
}

 所有函数的输出结果

I am a client this English is: apple
I am a Server ,The words that the client needs to translate -> apple <-> 苹果

 二、实际应用

下面写一个很简单的回调实际应用

就是通过客户端发送一个apple,之后服务端通过回调进行发送一个苹果

UdpServer.h 

using func_t = std::function<void(const std::string& , std::string* )>;class UdpServer
{
public:UdpServer(int port, func_t callback): _port(port), _sockfd(-1), _callback(callback){}~UdpServer(){if (_sockfd != -1){::close(_sockfd);}}bool Init(){// create socket_sockfd = socket(AF_INET, SOCK_DGRAM, 0);std::cout << "Create socket: " << _sockfd << std::endl;// bind socketstruct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = ::htons(_port);local.sin_addr.s_addr = INADDR_ANY;int n = ::bind(_sockfd, (struct sockaddr *)(&local), sizeof(local));std::cout << "Bind socket success: " << n << std::endl;return true;}void Start(){while (true){char inbuffer[1024]; struct sockaddr_in peer;socklen_t len = sizeof(peer);// 接受数据ssize_t n = ::recvfrom(_sockfd, inbuffer, sizeof(inbuffer) - 1, 0, (struct sockaddr *)(&peer), &len);if (n > 0){inbuffer[n] = 0;uint16_t clientport = ::ntohs(peer.sin_port);      // 客户端portstd::string clientip = ::inet_ntoa(peer.sin_addr); // 客户端ipstd::cout << "Received message from " << clientip << ":" << clientport << " sockfd: " << _sockfd << " Message: " << inbuffer << std::endl;std::string echo_string = "echo# ";echo_string += inbuffer;// 调用回调函数_callback(inbuffer, &echo_string);::sendto(_sockfd, echo_string.c_str(), echo_string.size(), 0, (struct sockaddr *)(&peer), len);}}}private:int _port;int _sockfd;func_t _callback;
};

Dict.h

class Translation
{
public:void translate(const std::string& word, std::string* transltion){std::cout << "client: " << word << std::endl;*transltion += " 苹果";}
};

UdpServer.cpp 

int main(int argc,char *argv[])
{if(argc != 2){std::cerr << "Usage: "<< argv[0] << " serverip serverport" << std::endl;exit(1);}uint16_t serverport = std::stoi(argv[1]);Translation t;// 法一// auto callback = std::bind(&Translation::translate,&t,std::placeholders::_1,std::placeholders::_2);// UdpServer server(serverport,callback);// 法二UdpServer server(serverport,[&t] (const std::string& word, std::string* transltion) {t.translate(word, transltion);});server.Init();server.Start();return 0;
}

UdpClient.cpp 

int main(int argc,char *argv[])
{if(argc != 3){std::cerr << "Usage: "<< argv[0] << " serverip serverport" << std::endl;exit(1);}std::string serverip = argv[1];uint16_t serverport = std::stoi(argv[2]);int sockfd = ::socket(AF_INET,SOCK_DGRAM,0);// 1. 创建socketif(sockfd < 0){std::cerr << "socket error"<<std::endl;exit(1);}// 1.1填充信息struct sockaddr_in server;memset(&server,0,sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(serverport);server.sin_addr.s_addr = ::inet_addr(serverip.c_str());// 2. clientdonewhile(true){std::cout << "Please Enter# ";std::string message;std::getline(std::cin,message);int n = ::sendto(sockfd,message.c_str(),message.size(),0,(struct sockaddr*)(&server),sizeof(server));struct sockaddr_in temp;socklen_t len = sizeof(temp);char buffer[1024];n = :: recvfrom(sockfd,buffer,sizeof(buffer) - 1,0,(struct sockaddr*)(&temp),&len);if(n > 0){buffer[n] = 0;std::cout << buffer << std::endl;}}return 0;
}

这里只输出了客户端的消息 

Please Enter# apple
echo# apple 苹果
Please Enter# 

http://www.xdnf.cn/news/503137.html

相关文章:

  • 计算机视觉与深度学习 | Python实现EEMD-LSTM时间序列预测(完整源码和数据)
  • JavaScript基础-预解析
  • 线程(二)OpenJDK 17 中线程启动的完整流程用C++ 源码详解之主-子线程通信机制
  • 如何彻底清空docker里面不使用的容器?
  • deepin v23.1 搜狗输入法next配置中文输入法下默认用英文标点
  • 符合Python风格的对象(对象表示形式)
  • 【机器学习】第二章模型的评估与选择
  • 【LeetCode】大厂面试算法真题回忆(91)--几何平均值最大子数组
  • vue引用cesium,解决“Not allowed to load local resource”报错
  • 调用DeepSeek系列模型问答时,输出只有</think>标签,而没有<think>标签
  • 无人机视角垃圾检测数据集VOC+YOLO格式771张1类别
  • 使用Maven和Ant上传文件到Linux服务器
  • 交流学习 | 江西同为科技有限公司赴海尔总部考察交流
  • Vue3学习(组合式API——父、子组件间通信详解)
  • 大模型之RAG知识库
  • 实验三:计划任务和时钟同步
  • 经典算法 求C(N, K) % mod,保证mod是质数
  • 打造文本差异对比工具 TextDiffX:从想法到实现的完整过程
  • 嵌入式软件的分层架构
  • GitHub 趋势日报 (2025年05月16日)
  • H3C UIS 超融合管理平台原理解读以及日常运维实操与故障处理
  • Transformer 架构在目标检测中的应用:YOLO 系列模型解析
  • 便捷的批量打印工具推荐
  • PyQt5基本窗口控件(QSlider(滑动条))
  • 【计网】 ARP地址解析协议 [工作过程]
  • hyper-v 虚拟机怎么克隆一台一样的虚拟机?
  • NHANES指标推荐:FMI
  • 【Linux笔记】——Linux线程控制创建、终止与等待|动态库与内核联动
  • 软件测试的常用的面试题【带答案】
  • 【汇总】影视仓接口地址,影视仓最新配置接口【2025.5】