剖析并实现C++17新特性的Any类型

问题:

对于这样的场景:对于一些CS(客户端-服务端)模型,当用户在客户端传入相应的事件时,我们需要实现框架即在服务端去分配线程处理这些事件,即调用用户的事件处理函数,那么对于不同的用户的事件函数,如何统一在服务端进行处理呢,那么容易想到的一个方法就是多态,如下:

class Task  // 服务端实现的
{
public:Task();~Task() = default;// 用户可以自定义任意任务类型,从Task继承,重写run方法,实现自定义任务处理virtual Any run() = 0;};
class MyTask : public Task //用户端想要处理的事件
{
public:MyTask(int begin, int end){}Any run() {... //用户的事件return sum; //处理的结果返回}};

此时服务端,就可以调用派生类的run方法实现用户的事件了,此时问题就出现了,那么用户如何获取事件处理的返回结果呢,要知道多态重写的是同名函数,包括返回值,所以我们需要一个统一的Any类型接收任意类型的参数返回,如int、string、vector等,如上所示

ps:模板和继承无法共存,也就是不能给run方法添加模返回参数,只能使用自定义的Any类型接收所有的返回类型。

简要来说,我需要一个统一类型接收所有类型,并且统一类型可以推断接收的所有类型它到底是什么类型

Any的设计思路

1:首先要接收任意的返回类型:即联想到模板

2:Any拥有可以一个统一的类型指向任意类型,即联想到继承

Any的实现

首先,Any类型接收一个任意类型的参数,也就是对其构造函数,模板化,同时拥有了一个成员指针,它是一个统一的指针,也就是接下来我会将它设计会基类的指针,以后会指向继承于它的派生类对象,注意我使用的是unique_ptr,所以手动声明了右值引用的拷贝和赋值,而删除了左值引用的拷贝和赋值(原因自查unique_ptr)

class Any
{
public:Any() = default;~Any() = default;Any(const Any&) = delete;Any& operator =(const Any&) = delete;Any(Any&&) = default;Any& operator=(Any&&) = default;template<typename T>Any(T data) {}  
private:std::unique_ptr<Base> base_;
};

 注意到,T data其实就是上文的 int sum,那么如何让base指针统一指向这些不同的对象呢,就是把base作为基类指针,构造初始化的时候,将data去初始化一个继承于base的派生类对象,然后让base指向这个派生类对象,就完成了统一类型指向任意类型了。也就是在下面,我继续实现了继承的关系方法。

class Any
{
public:Any() = default;~Any() = default;Any(const Any&) = delete;Any& operator =(const Any&) = delete;Any(Any&&) = default;Any& operator=(Any&&) = default;template<typename T>Any(T data) : base_(std::make_unique<Derive<T>>(data)){}  private:class Base{public:virtual ~Base() = default;};//template<typename T>class Derive : public Base {public:Derive(T data): data_(data){}T data_;};
private:std::unique_ptr<Base> base_;
};

 最后,用户最后得到的Any对象:Any res = ...,这是一个任意对象,如何变为用户的事件处理的结果的类型呢,就需要进行转换,因为T data就表示int sum,那么就想到我们需要从base里面找到我指向的派生类对象,所以利用类型的转换,这里是基类向派生类转换,所以用到了dynamic_cast的安全转换,然后取出Derive_对象的成员data_就完成了,整体如下:

#include<iostream>
#include <memory>class Any
{
public:Any() = default;~Any() = default;Any(const Any&) = delete;Any& operator =(const Any&) = delete;Any(Any&&) = default;Any& operator=(Any&&) = default;template<typename T>Any(T data) : base_(std::make_unique<Derive<T>>(data)){}  template<typename T>T cast(){Derive<T> *pd = dynamic_cast<Derive<T>*> (base_.get());if (pd == nullptr){std::cout << "type unmatch" << std::endl;}return pd->data_;}private:class Base{public:virtual ~Base() = default;};//template<typename T>class Derive : public Base {public:Derive(T data): data_(data){}T data_;};
private:std::unique_ptr<Base> base_;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/840016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中文信息期刊投稿邮箱

《中文信息》杂志是国家新闻出版总署批准的国家级刊物&#xff08;月刊&#xff09;&#xff0c;国内外公开发行&#xff0c;大十六开印刷。本刊主要反映我国中文信息处理的学术水平&#xff0c;重点刊登科技、经济、教育等领域的基础理论、科研与应用技术的学术论文&#xff0…

Rust:如何使用 Pytorch 深度学习模型?

以下笔记内容仅供参考&#xff0c;尚未进行实际验证。 在Rust中使用PyTorch通常涉及使用一个称为tch的第三方crate&#xff0c;它是PyTorch的C API的Rust绑定。下面是一个简单的例子&#xff0c;展示了如何在Rust程序中加载一个PyTorch模型并进行预测。 首先&#xff0c;你需要…

第2天 搭建安全拓展_小迪网络安全笔记

1.常见搭建平台脚本使用: 例如 phpstudy IIS Nginx(俗称中间件): 什么是中间件: 中间件是介于应用系统和系统软件之间的一类软件&#xff0c;它使用系统软件所提供的基础服务&#xff08;功能&#xff09;&#xff0c;衔接网络上应用系统的各个部分或不同的应用&#…

vue2引入brand.vue和brand-add-or-update.vue后重启项目报错解决方案

最近在用粒谷商城项目练手&#xff0c;学习到P59时引入品牌两个vue文件&#xff0c;重启(npm run dev)项目报错: ERROR Failed to compile with 2 errors 12:11:59Th…

前端调用浏览器录音功能且生成文件(vue)

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 首先在页面中给两个按钮&#xff0c;分别是“开始录音”&#xff0c;“结束录音”。以及录音成功后生成一个下载语音的链接。 1. 先看页面展示 <template><div><button click"startRecording…

【论文阅读】Rank-DETR(NIPS‘23)

paper:https://arxiv.org/abs/2310.08854 code:https://github.com/LeapLabTHU/Rank-DETR

Go 生成UUID唯一标识

什么是UUID 通用唯一识别码&#xff08;英语&#xff1a;Universally Unique Identifier&#xff0c;简称UUID&#xff09;是一种软件建构的标准&#xff0c;亦为自由软件基金会组织在分散式计算环境领域的一部份。 UUID的目的&#xff0c;是让分散式系统中的所有元素&#x…

微信小程序视频怎么保存到本地

你是否遇到过在微信小程序中发现了精彩的视频&#xff0c;却不知道如何将其保存到本地的困扰&#xff1f;别担心&#xff0c;这篇文章将为您揭示2024年最新的保存方法&#xff0c;让您轻松下载和保留这些珍贵的视频内容。不管您是使用安卓设备还是苹果设备&#xff0c;我们都为…

SD3303A大功率高精度LED驱动芯片3W低功耗高效率工作温度40c+85%

SD3303A是一款大功率高亮度LED驱动芯片&#xff0c;可以提供 1A的电流驱动3W的LED。具有高效率&#xff0c;低功耗等特点 &#xff0c;适用于电池供电的LED照明设备。 SD3303A具有开路保护和过温保护。 SD3303A需要使用两颗10uF(或者更大)的瓷 片电容&#xff0c;来保证电路性能…

学生手机管理方案

咱们现在的学生&#xff0c;手机几乎成了标配。所以问题就来了&#xff0c;怎么管理这些手机&#xff0c;让手机在课堂上不成为学习的干扰&#xff1f; 先得搞明白&#xff0c;手机在学生手里上该扮演什么角色。手机确实能帮学生查资料、交流学习&#xff0c;甚至写作业&#x…

Log360:护航安全,远离暗网风险

暗网有时候就像是一个神秘的地下世界&#xff0c;是互联网的隐蔽角落&#xff0c;没有任何规则。这是一个被盗数据交易、网络犯罪分子策划下一步攻击的地方。但仅仅因为它黑暗&#xff0c;不意味着你要对潜在的威胁视而不见。 暗网 这就是ManageEngine Log360的用武之地&…

用Visual Studio进行Qt开发的Cmake模板

使用Visual Studio进行Qt开发的时候&#xff0c;我们可以借用Cmake的moc功能和相应对Qt的支持生成VS工程。 文件组织 Root │ cmake.sh // cmake执行脚本 │ CMakeLists.txt // 根目录cmake文件 │ README.md │ text.txt ├─bin …

【Oracle篇】rman工具实用指南:常用命令详解与实践(第二篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

chatgpt功能真的强大好用吗?

最近听到很多人说chatgpt的功能强大&#xff0c;非常好用。 我有点好奇&#xff0c;于是试用了一下&#xff0c;问了几个最近搜索过的问题&#xff0c;以检验chatgpt的能力。 1、如何解非线性方程 解非线性方程的方法有很多&#xff0c;取决于方程的具体形式和所需的精度。以…

WPF拖放控件

拖放官方文档 拖放操作通常涉及两个参与方&#xff1a;拖动对象所源自的拖动源和接收放置对象的拖放目标。 拖动源和放置目标可能是相同应用程序或不同应用程序中的 UI 元素。 我这里实现的是对TabControl的Tab页面进行拖放&#xff0c;以达成类似Chrome浏览器的拖放功能。 …

【Webpack】webpack scope hoisting

scope hoisting 是 webpack 的内置优化&#xff0c;它是针对模块的优化&#xff0c;在生产环境打包时会自动开启。 在未开启 scope hoisting 时&#xff0c;webpack 会将每个模块的代码放置在一个独立的函数环境中&#xff0c;这样是为了保证模块的作用域互不干扰。 而 scope…

【Centos7+JDK1.8】Jenkins安装手册

一、安装环境 Centos7 JDK1.8 Jenkins-2.346.3 JDK1.8安装以及网络配置等 自行搜索资料解决。 二、卸载历史安装的Jenkins&#xff0c;直接全部复制粘贴下面的命令 service jenkins stop yum -y remove jenkins rpm -e jenkins rpm -ql jenkins rm -rf /etc/sysconfig/je…

解决远程链接的“Gtk-WARNING **: cannot open display;

1.需要检查ssh配置中X11Forwarding是否启用 2.检查本地ssh工具是否启用x11转发&#xff08;下图以mobaxterm为例&#xff09; 3.检查是否有防火墙等其他网络拦截&#xff0c;如果没有特殊需求&#xff0c;这里可以直接将防火墙服务关闭 4.按上诉操作检查后&#xff0c;正常情况…

P2P服务端模型配合 Tool.net P2pServerAsync 类使用

Tool.Net 支持的 P2P 服务器模型实例 说明服务器部分相关代码相关调用实例Tcp版本Udp版本 最后附一张思维图 说明 当前文章&#xff0c;仅是Tool.Net 开源库的一个缩影。本次更新V5.0版本以上提供支持。可以提供简单实现P2P功能用于业务开发。 服务器部分相关代码 完整代码&…

JVM运行时内存:垃圾回收器(Serial ParNew Parallel )详解

文章目录 1. 查看默认GC2. Serial GC : 串行回收3. ParNew GC&#xff1a;并行回收4. Parallel GC&#xff1a;吞吐量优先 1. 查看默认GC -XX:PrintCommandLineFlags&#xff1a;查看命令行相关参数&#xff08;包含使用的垃圾收集器&#xff09;使用命令行指令&#xff1a;ji…