管理器注册类方法和调用类函数方法

重点:

1.将要创建的类管理起来,当面临一类构件的注册管理的实现。

2.包括调用函数内部类方法。

一:定义结构体和基类

Define.h

enum class MyType
{red,blue,green,black
};class BaseTool
{
public:BaseTool() = default;virtual ~BaseTool()=default;private:};

二:设计单例管理类

RegMananger.h

#pragma once
#include "Define.h"
#include <iostream>
#include <cstdarg>
#include <set>class ICreator
{
public:virtual ~ICreator() {}virtual std::shared_ptr<BaseTool> Create() = 0;
};//单例管理注册信息
class RegMananger
{
public:static RegMananger& Getinstance();RegMananger(const RegMananger&) = delete;RegMananger& operator=(const RegMananger&) = delete;public:void AddMananger(MyType type, ICreator* create);std::shared_ptr<BaseTool> GetEditor(MyType type);
private:RegMananger();~RegMananger();//保证类的私密性struct Impl;Impl* m_pData;
};//计算可变参数个数,限制在20个
#define ARG_T(t)  t  //解决VC编译错误
#define ARG_N(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,N,...)  N //截取并返回第四个参数,这里限制了可变参数计算的范围[1,4]
#define ARG_N_HELPER(...)  ARG_T(ARG_N(__VA_ARGS__))   //辅助宏
#define COUNT_ARG(...)  ARG_N_HELPER(__VA_ARGS__,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)  //返回可变参数个数//注册宏函数
#define REG_TOOL(CLASSNAME, ...) \
class AutoReg##CLASSNAME :public ICreator \
{ \
public:\AutoReg##CLASSNAME()\{\std::set<MyType>&& typeSet{GetType(COUNT_ARG(__VA_ARGS__),__VA_ARGS__)};\for (auto& var:typeSet)\{\RegMananger::Getinstance().AddMananger(var,this);\}\}\
public:	\virtual std::shared_ptr<BaseTool> Create() override	\{	\return std::make_shared<BaseTool>();	\}	\
private: \std::set<MyType> GetType(int n, ...)\{\std::set<MyType> myType; \va_list args; \va_start(args, n); \while (n--)\{\MyType ty = va_arg(args, MyType); \myType.insert(ty); \}\va_end(args); \return myType; \}\
}; \
static AutoReg##CLASSNAME _regEditorCreator##CLASSNAME;	\
//通过static去实现实例化

RegMananger.cpp 

#include <map>
#include "RegMananger.h"struct RegMananger::Impl
{std::map<MyType, ICreator*> m_mapEditor;
};RegMananger& RegMananger::Getinstance()
{static RegMananger m_instance;return m_instance;
}RegMananger::RegMananger()
{m_pData = new Impl();
}RegMananger::~RegMananger()
{delete m_pData;
}void RegMananger::AddMananger(MyType type, ICreator* create)
{m_pData->m_mapEditor[type] = create;
}std::shared_ptr<BaseTool> RegMananger::GetEditor(MyType type)
{auto iter = m_pData->m_mapEditor.find(type);if (iter == m_pData->m_mapEditor.end()){return nullptr;}return iter->second->Create();
}

三:注册类

RegMananger.h

#pragma once
#include "Define.h"class RedColorTool:public BaseTool
{
public:RedColorTool() = default;~RedColorTool() = default;private:int data;
};

RegMananger.cpp 

#include "RedColor.h"
#include "RegMananger.h"REG_TOOL(RedColorTool, MyType::red, MyType::blue);

四:调用基类

BaseCmd.h

#pragma once
#include "RegMananger.h"class BaseCmd
{
public:BaseCmd() = default;virtual ~BaseCmd() = default;void SetType(MyType type) { m_type = type; };std::shared_ptr<BaseTool>  GetBaseTool(){return RegMananger::Getinstance().GetEditor(m_type);};protected:template<class _Tool, class _Ret, class ..._Arg>//_Ret:返回值,_Tool类名称,func:static函数,_Arg:函数传入参数_Ret InvokeTool(_Ret(_Tool::* func)(_Arg...), std::remove_cv_t<_Arg>... args){std::shared_ptr<_Tool> spEditor = std::dynamic_cast<_Tool*>(GetBaseTool());if (spEditor){if constexpr (std::is_same_v<_Ret,void>){(spEditor.get()->*func)(std::forward<_Arg>(args)...);}else{return (spEditor.get()->*func)(std::forward<_Arg>(args)...);}}else{std::cout << "class Error" << std::endl;}if constexpr (!std::is_same_v<_Ret, void>){return _Ret{};}}private:MyType m_type;
};

 五:普通类

#pragma once
#include "Define.h"
#include "RegMananger.h"class ColorTool :public BaseTool
{
public:ColorTool() =default;~ColorTool() = default;bool Create(int num,bool check);
private:};bool ColorTool::Create(int num, bool check)
{return true;
}REG_TOOL(ColorTool, MyType::red, MyType::blue);

六:继承调用类

#pragma once
#include "BaseCmd.h"
#include "ColorTool.h"class NewColorCmd:public BaseCmd
{
public:NewColorCmd() { SetType(MyType::red); };~NewColorCmd()=default;void Create();
private:};void NewColorCmd::Create()
{int num = 10;bool check = true;InvokeTool(&ColorTool::Create, num, check);
}

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

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

相关文章

LINUX和UBUNTU收集物理机设备信息的脚本

能通配一部份的设备,实际应用中可根据实际情况进行完善 #!/bin/bash >mtmp1.txt.txt >mtmp2.txt.txt >cputmp1.txt.txt >cputmp2.txt.txt >disktmp1.txt.txt >disktmp2.txt.txt >bdtmp1.txt.txt >bdtmp2.txt.txt >Powertmp1.txt.txt >Powertmp2…

Java @Override 注解

在代码中&#xff0c;你可能会看到大量的 Override 注解。 这个注解简单来说就是让编译器去读的&#xff0c;能够避免你在写代码的时候犯一些低级的拼写错误。 Java Override 注解用来指定方法重写&#xff08;Override&#xff09;&#xff0c;只能修饰方法并且只能用于方法…

使用Pyhton执行JavaScript-pyexecjs

安装 pip install pyexecjs使用案例 import execjs print(execjs.eval("abc zxc".split(" ")))# 调用变量名 text execjs.compile(open(rtext.js).read()) print(text.eval(d))执行call function # text.js 文件 var t 1; function add(a, b) {return a…

怎么将Linux上的文件上传到github上

文章目录 1. 先在window浏览器中创建一个存储项目的仓库2. 复制你的ssh下的地址1) 生成ssh密钥 : 在Linux虚拟机的终端中,运行以下命令生成ssh密钥2)将ssh密钥添加到github账号 : 运行以下命令来获取公钥内容: 3. 克隆GitHub存储库&#xff1a;在Linux虚拟机的终端中&#xff0…

leetcode42 接雨水

题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高…

es6.x和es7.x如何创建索引?

一、es6.x {"settings": {"number_of_shards": "2","number_of_replicas": "2","max_result_window": 100000},"mappings": {"doc": {"dynamic": "strict","prope…

Golang网络编程:即时通讯系统Instance Messaging System

系统基本架构 版本迭代 项目改造 无人机是client&#xff0c;我们是server&#xff0c;提供注册登入&#xff0c;场景选择等。信道模拟器是server&#xff0c;我们是client&#xff0c;我们向信道模拟器发送数据&#xff0c;等待信道模拟器计算结果&#xff0c;返回给无人机。…

Java反射的详细解析一

1. 反射 1.1 反射的概述&#xff1a; 专业的解释&#xff08;了解一下&#xff09;&#xff1a; 是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b; 对于任意一个对象&#xff0c;都能够调用它的任意属性和方法&#xff…

使用ChatGPT和MindShow一分钟生成PPT模板

对于最近学校组织的实习答辩&#xff0c;由于时间太短了&#xff0c;而且小编也特别的忙&#xff0c;于是就用ChatGPT结合MindShow一分钟快速生成PPT&#xff0c;确实很实用。只要你跟着小编后面&#xff0c;你也可以快速制作出这个PPT&#xff0c;下面小编就来详细介绍一下&am…

联想M7216NWA一体机连接WiFi及手机添加打印机方法

联想M7216NWA一体机连接WiFi方法&#xff1a; 1、首先按打印机操作面板上的“功能键”&#xff1b;【用“”&#xff08;上翻页&#xff09;“-”&#xff08;下翻页&#xff09;来选择菜单的内容】 2、下翻页键找到并选择“网络”&#xff0c;然后“确认键”&#xff1b; 3…

[leetcode] 2578.最小分割和

给你一个正整数 num &#xff0c;请你将它分割成两个非负整数 num1 和 num2 &#xff0c;满足&#xff1a; num1 和 num2 直接连起来&#xff0c;得到 num 各数位的一个排列。 换句话说&#xff0c;num1 和 num2 中所有数字出现的次数之和等于 num 中所有数字出现的次数。 num…

自动驾驶技术的基础知识

自动驾驶技术是现代汽车工业中的一项革命性发展&#xff0c;它正在改变着我们对交通和出行的理解。本文将介绍自动驾驶技术的基础知识&#xff0c;包括其概念、历史发展、分类以及关键技术要素。 1. 自动驾驶概念 自动驾驶是一种先进的交通技术&#xff0c;它允许汽车在没有人…

Docker安装——Ubuntu (Jammy 22.04)

一、为什么要用 Ubuntu&#xff1f;(centos和ubuntu有什么区别&#xff09; 使用lsb_release命令&#xff1a;lsb_release -a &#xff0c;即可查看ubantu的版本&#xff0c;但是为什么要使用ubantu 呢&#xff1f; 区别&#xff1a;1、centos基于EHEL开发&#xff0c;而ubunt…

三十三、【进阶】索引的分类

1、索引的分类 &#xff08;1&#xff09;总分类 主键索引、唯一索引、常规索引、全文索引 &#xff08;2&#xff09;InnoDB存储引擎中的索引分类 2、 索引的选取规则(InnoDB存储引擎) 如果存在主键&#xff0c;主键索引就是聚集索引&#xff1b; 如果不存在主键&#xff…

浅析前端单元测试

对于前端来说&#xff0c;测试主要是对HTML、CSS、JavaScript进行测试&#xff0c;以确保代码的正常运行。 常见的测试有单元测试、集成测试、端到端&#xff08;e2e&#xff09;的测试。 单元测试&#xff1a;对程序中最小可测试单元进行测试。我们可以类比对汽车的测试&…

最新 SpringCloud微服务技术栈实战教程 微服务保护 分布式事务 课后练习等

SpringCloud微服务技术栈实战教程&#xff0c;涵盖springcloud微服务架构Nacos配置中心分布式服务等 SpringCloud及SpringCloudAlibaba是目前最流行的微服务技术栈。但大家学习起来的感受就是组件很多&#xff0c;不知道该如何应用。这套《微服务实战课》从一个单体项目入手&am…

RK3588开发笔记-MIPI-CSI接口视频解码芯片XS9922B调试

目录 前言 一、RK3588 MIPI接口介绍 二、xs9922B视频解码芯片介绍 三、原理图连接

C++项目:仿mudou库one thread one loop式并发服务器实现

目录 1.实现目标 2.HTTP服务器 3.Reactor模型 3.1分类 4.功能模块划分: 4.1SERVER模块: 4.2HTTP协议模块: 5.简单的秒级定时任务实现 5.1Linux提供给我们的定时器 5.2时间轮思想&#xff1a; 6.正则库的简单使用 7.通用类型any类型的实现 8.日志宏的实现 9.缓冲区…

深度学习 图像分割 PSPNet 论文复现(训练 测试 可视化)

Table of Contents 一、PSPNet 介绍1、原理阐述2、论文解释3、网络模型 二、部署实现1、PASCAL VOC 20122、模型训练3、度量指标4、结果分析5、图像测试 一、PSPNet 介绍 PSPNet(Pyramid Scene Parsing Network)来自于CVPR2017的一篇文章&#xff0c;中文翻译为金字塔场景解析…

YOLOv7暴力涨点:Gold-YOLO,遥遥领先,超越所有YOLO | 华为诺亚NeurIPS23

💡💡💡本文独家改进:提出了全新的信息聚集-分发(Gather-and-Distribute Mechanism)GD机制,Gold-YOLO,替换yolov7 head部分 实现暴力涨点 Gold-YOLO | 亲测在多个数据集能够实现大幅涨点,适用各个场景的涨点 收录: YOLOv7高阶自研专栏介绍: http://t.csdnim…