1.1.C++项目:仿muduo库实现并发服务器之any类的设计

文章目录

一、思想

每⼀个Connection对连接进行管理,最终都不可避免需要涉及到应用层协议的处理,因此在Connection中需要设置协议处理的上下文来控制处理节奏。但是应用层协议千千万,为了降低耦度,这个协议接收解析上下文就不能有明显的协议倾向,它可以是任意协议的上下文信息,因此就需要⼀个通⽤的类型来保存各种不同的数据结构。

在C语言中,通用类型可以使用void*来管理,但是在C++中,boost库和C++17给我们提供了一个通用类型any来灵活使用,如果考虑增加代码的移植性,尽量减少第三方库的依赖,则可以使用C++17特性中的any,或者自己来实现。而这个any通用类型类的实现其实并不复杂,以下是简单的部分实现。

二、框架

cpp 复制代码
/*Any类主要是实现⼀个通⽤类型出来,在c++17和boost库中都有现成的可以使⽤,但是这⾥实现⼀下
了解其思想,这样也就避免了第三⽅库的使⽤了*/

/*⾸先Any类肯定不能是⼀个模板类,否则编译的时候 Any<int> a, Any<float>b,需要传类型作
为模板参数,也就是说在使⽤的时候就要确定其类型*/
/*这是⾏不通的,因为保存在Content中的协议上下⽂,我们在定义any对象的时候是不知道他们的协
议类型的,因此⽆法传递类型作为模板参数*/
/*因此考虑Any内部设计⼀个模板容器holder类,可以保存各种类型数据*/
/*⽽因为在Any类中⽆法定义这个holder对象或指针,因为any也不知道这个类要保存什么类型的数
据,因此⽆法传递类型参数*/
/*所以,定义⼀个基类placehoder,让holder继承于placeholde,⽽Any类保存⽗类指针即可*/
/*当需要保存数据时,则new⼀个带有模板参数的⼦类holder对象出来保存数据,然后让Any类中的⽗
类指针,指向这个⼦类对象就搞定了*/

三、代码

cpp 复制代码
class Any{
    private:
        class holder {
            public:
                virtual ~holder() {}
                virtual const std::type_info& type() = 0;
                virtual holder *clone() = 0;
        };
        template<class T>
        class placeholder: public holder {
            public:
                placeholder(const T &val): _val(val) {}
                // 获取子类对象保存的数据类型
                virtual const std::type_info& type() { return typeid(T); }
                // 针对当前的对象自身,克隆出一个新的子类对象
                virtual holder *clone() { return new placeholder(_val); }
            public:
                T _val;
        };
        holder *_content;
    public:
        Any():_content(NULL) {}
        template<class T>
        Any(const T &val):_content(new placeholder<T>(val)) {}
        Any(const Any &other):_content(other._content ? other._content->clone() : NULL) {}
        ~Any() { delete _content; }

        Any &swap(Any &other) {
            std::swap(_content, other._content);
            return *this;
        }

        // 返回子类对象保存的数据的指针
        template<class T>
        T *get() {
            //想要获取的数据类型,必须和保存的数据类型一致
            assert(typeid(T) == _content->type());
            return &((placeholder<T>*)_content)->_val;
        }
        //赋值运算符的重载函数
        template<class T>
        Any& operator=(const T &val) {
            //为val构造一个临时的通用容器,然后与当前容器自身进行指针交换,临时对象释放的时候,原先保存的数据也就被释放
            Any(val).swap(*this);
            return *this;
        }
        Any& operator=(const Any &other) {
            Any(other).swap(*this);
            return *this;
        }
};
相关推荐
郝学胜-神的一滴25 分钟前
Linux系统函数link、unlink与dentry的关系及使用注意事项
linux·运维·服务器·开发语言·前端·c++
赵杰伦cpp26 分钟前
list的迭代器
开发语言·数据结构·c++·算法·链表·list
无妄无望27 分钟前
docker学习 (3)网络与防火墙
网络·学习·docker
Pota-to成长日记34 分钟前
2025/10/14 redis断联 没有IPv4地址 (自用)
linux·运维·服务器
TG_yunshuguoji38 分钟前
阿里云渠道商:哪些方法能给服务器加速?
服务器·阿里云·云计算
老歌老听老掉牙1 小时前
使用 OpenCASCADE 提取布尔运算后平面图形的外轮廓
c++·平面·opencascade
闻缺陷则喜何志丹1 小时前
【动态规划】数位DP的原理、模板(封装类)
c++·算法·动态规划·原理·模板·数位dp
詩句☾⋆᭄南笙1 小时前
HTML列表、表格和表单
服务器·前端·html·表格·列表·表单
胖咕噜的稞达鸭1 小时前
二叉树搜索树插入,查找,删除,Key/Value二叉搜索树场景应用+源码实现
c语言·数据结构·c++·算法·gitee
tomcsdn412 小时前
SMTPman,smtp服务器高效邮件发送核心指南
服务器·邮件营销·邮件群发·smtp服务器·域名邮箱·邮件服务器·红人营销