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

C++项目:仿muduo库高并发服务器--------Any类的实现


文章目录

  • 前言
  • 一、服务器连接管理与通用协议上下文设计
  • 二、Any类的设计思路
  • 三、代码实现


前言

本篇文章是博主在学习仿muduo库高并发服务器项目所用到的功能模块,旨在设计一个可以存储任意类型的Any类。


一、服务器连接管理与通用协议上下文设计

在服务器的连接管理中,每个Connection对象负责一条客户端连接的管理,其必然涉及应用层协议的处理(如请求解析等)。因此,Connection内部必须设置协议处理上下文——用于记录协议解析进度、暂存中间数据(如:解析协议得到的数据),从而控制协议处理的节奏(例如应对网络通信中常见的粘包、半包问题)。
我们得到的数据包可能不是一个完整的请求,但是我们依然需要对数据包解析,这时就可以将本次解析得到的信息存储起来,直到得到一个完整的请求
本项目需要满足不同应用层协议(如 HTTP、TCP 私有协议 等),若让协议上下文与特定协议强绑定,会大幅提升代码耦合度:后续新增或修改协议时,需频繁调整Connection的逻辑。为解决这一问题,协议的接收与解析上下文必须具有通用性,能够适配任意协议的上下文信息存储需求,这就需要一种可容纳不同数据结构的 “通用类型” 来承载

从技术实现来看,不同语言 / 标准库提供了不同的通用类型解决方案:

  • 在 C 语言中,通常通过void*(无类型指针) 实现通用数据管理,但这种方法不仅操作繁琐,还容易因类型不匹配引发安全问题
  • 在 C++ 中,可借助第三方库(如 Boost 库的boost::any),或使用 C++17 标准原生支持的std::any—— 二者均能安全存储任意类型的数据。

考虑到本项目的移植性,这里我们自己实现轻量级的any类

二、Any类的设计思路

需求:

  • 一个连接需要有,请求接收与解析的上下文。
  • 上下文类型不固定,服务器支持多种协议,不同协议上下文结构不同。
  • 结论:得有能保存各种不同类型结构数据的容器。
  • 任务:设计实现一个any类,且它是一个可以存储任意类型的容器。

这里可能多数人的第一反应是,使用类模板,但是这种方法在实例化对象时必须指定数据类型,实例后次类型就固定了,而这里我们需要的是可以存储任意类型的数据显然这是不合理的.

要满足“存储任意类型且无需在实例化时固定类型”的需求,可利用类继承 + 多态 + 类型擦除的思路设计 Any 类:

Any 类内部嵌套一个抽象基类(用于“类型擦除”,屏蔽具体类型差异),再通过模板子类承接具体数据的存储。借助多态特性,Any 能间接持有任意类型的对象,且无需在创建 Any 实例时预先指定存储类型。

结合代码理解

三、代码实现

为帮助大家理解如何达到消除类型的效果,下面代码借用AI注释

#include<iostream>
#include<cassert>
#include<typeinfo>
#include<string>
class Any{
public:Any():_content(nullptr){}template<class T>Any(const T&val):_content(new placeholder<T>(val)){}Any(const Any&other):_content(other._content?other._content->clone():nullptr){}//先判空,若不为空就拷贝Any&operator=(const Any&other){Any(other).Swap(*this);return *this;}template<class T>//赋值重载Any&operator=(const T&val){Any(val).Swap(*this);return *this;}Any&Swap(Any&other){std::swap(this->_content,other._content);return *this;}template<class T>//返回子类对象,存储数据的指针T*get(){assert(typeid(T)==_content->type());return &(((placeholder<T>*)_content)->_val);}~Any(){delete _content;}private:
//holder 是一个纯抽象基类,它的关键特点是:完全不包含任何具体类型的信息,只定义了三个通用接口
//这个基类的作用是 “制定统一标准”:无论存储的具体类型是什么(int/string/ 自定义类型)
//对外都必须通过这三个接口交互。从这一层开始,“具体类型” 的细节就被隐藏了。class holder{public:virtual ~holder(){}virtual  holder*clone()=0;virtual const std::type_info& type()=0;//查看存储类型};
//placeholder<T> 是模板类,它继承自 holder,但与具体类型 T 绑定
//向下:直接操作具体类型 T(存储 _val、拷贝 _val);
//向上:通过重写 holder 的接口,将 T 的细节 “包装” 成通用接口。template<class T>class placeholder:public holder{public:placeholder(const T&val):_val(val){}virtual holder* clone(){return new placeholder(_val);}//根据自己克隆一个新的对象virtual const std::type_info& type(){return typeid(T);}//获取存储对象类型T _val;};holder* _content;
};
//Any 类是最终对外的 “容器”,它的核心成员是 holder* _content,这个指针指向 placeholder<T> 实例,但 Any 类本身 完全不知道 T 是什么
//存储时:无论传入 int、string 还是自定义类型,都被 placeholder<T> 封装成 holder*,Any 无需关心 T;
//传递时:Any 对象的拷贝 / 赋值(如 a = b)通过 holder 的 clone() 接口完成,与具体类型无关;
//取值时:才通过 type() 接口校验类型,再转换回 T*—— 但这个 “类型恢复” 是使用者主动指定 T 的结果,Any 本身仍不感知 T。//测试
// class Test{
//     public:
//     Test()
//     {
//         std::cout<<"构造"<<std::endl;
//     }
//     Test(const Test&t)
//     {
//         std::cout<<"拷贝"<<std::endl;
//     }
//     ~Test()
//     {
//         std::cout<<"析构"<<std::endl;
//     }
// };
// int main()
// {
//     Any a;
//     a=10;
//     int *p=a.get<int>();
//     std::cout<<*p<<std::endl;
//     a=std::string("aaaa");
//     std::string*sp=a.get<std::string>();
//     std::cout<<*sp<<std::endl;//     Test t;
//     a=t;//     return 0;
// }
http://www.dtcms.com/a/406185.html

相关文章:

  • ELK 企业级日志分析系统实战教程
  • 驻马店怎么建设自己的网站wordpress 导出到pdf
  • 网站建设成本表一般什么行业做网站的多
  • 阳台光伏、储能系统再升级!双路电能表,您家能源的“智能管家”
  • 【Unity 入门教程】四、如何制作一个 Perfab
  • 浅谈高校门户网站建设的规范标准找做废薄膜网站
  • Word和WPS文字中的题注没有更新?全选按F9刷新
  • Spring Boot集群 集成Nginx配置:负载均衡+静态资源分离实战
  • 本地生活软件开发指南:从用户需求到商业闭环的实战逻辑
  • 建设网站需要租赁主机吗重庆模板建站代理
  • CSP-J/S初赛赛后总结
  • Leetcode 208. 实现 Trie (前缀树)
  • 国际型网站建设wordpress换网址插件
  • Dlib+OpenCV 人脸轮廓绘制
  • Spring Boot 整合 MySQL 和 Druid
  • 基于 STM32 的智能马桶控制系统设计与实现
  • SpringCloud 项目阶段九:Kafka 接入实战指南 —— 从基础概念、安装配置到 Spring Boot 实战及高可用设计
  • 徐州企业建站模板一个网站的制作过程
  • phpmysql网站开发项目式教程房地产开发公司招聘
  • python+springboot+uniapp基于微信小程序的巴马旅居养老系统 旅游养老小程序
  • 阿里云无影发布首个Agentic Computer形态的个人计算产品
  • PHP 8.0+ 元编程与编译时优化:构建下一代PHP框架
  • aws用ami新创建之后用密码登录不了
  • 安科瑞Acrel-1000DP分布式光伏监控系统:赋能光储充一体化,光功率预测助力电站高效运维与收益提升
  • 网站建设引擎旅游网站开发系统
  • 建设银行网站点不进去了怎么办网站全站开发
  • 【Java后端】Spring Boot 比 Spring 的优势:以 RESTful 接口开发为例 一文详解
  • 计算机软件工程毕设项目推荐—基于协同过滤算法的理财产品推荐系统(采用余弦相似度计算推荐,Python,Flask,Vue,Mysql,B/S架构)
  • docker-卷
  • 电子行业如何通过MES管理系统实现柔性制造,应对订单波动?