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

C++类对象反制机制实现_精简修改版

前几天写的类对象反射机制太烦锁了,今天写个修改版的,精简为两个类
一个是类的数据结构,另一个是类的父类对象,把所有操作类的方法都写到父类中

1.类的信息结构体

struct Field_Node
{TCHAR m_name[20];		//字段名称TCHAR m_typeName[20];	// 字段类型名称size_t m_typeHashCode;	//字段数据类型的哈希值size_t m_typeOffs;		//字段偏移量
};

字段信息结构不再添加其他方法了,就只为保存字段信息数据

2.父类QObject

class QObject
{
public:QObject(){}virtual ~QObject(){}public://静态方法获取子类对象,直接New一个子类对象就好了template<typename T>static QObject* CreateObject(){retrun new T();}//纯虚函数获得子类的字段信息数组地址virtual const Field_Node* GetSubClassFieldNode()const=0;//设置类对象的字段数据template<typename T>void Set_Value(const TCHAR* strFieldName, const T& inValue){//调用子类的,获得其静态的字段信息数组地址const Field_Node* pField=GetSubClassFieldNode(); //循环查找字段名称并给其赋值while(pField->m_typeHashCode!=0){if(lstrcmp(pField->m_name,strFieldName)==0){if(pField->m_typeHashCode!=typeid(T).hash_code()){assert(false && "数据类型不匹配,检查字段数据类型和输入的数据类型是否一致!!!");return;}//设置字段的值*((T*)((unsigned char*)&stu+ pField->m_typeOffs))=inValue;return;}pField++;}//end while}//获得字段数据void Get_Value(const TCHAR* strFieldName, T& outValue){//调用子类的,获得其静态的字段信息数组地址const Field_Node* pField=GetSubClassFieldNode(); //循环查找字段名称并给其赋值while(pField->m_typeHashCode!=0){if(lstrcmp(pField->m_name,strFieldName)==0){if(pField->m_typeHashCode!=typeid(T).hash_code()){assert(false && "数据类型不匹配,检查字段数据类型和输入的数据类型是否一致!!!");return;}//获取字段的值outValue=*((T*)((unsigned char*)&stu+ pField->m_typeOffs));return;}pField++;}//end while}};

这样就能对子类对象的字段进行数据操作了

3.下面是类的注册宏,在其内就重写一个父类的虚函数就搞定了,

//类内声明宏
#define REGISTER_CLASS_NAME()\
public:\
const Field_Node* GetSubClassFieldNode()const//类外实现宏
#define BEGIN_REGISTER_FILEDS_NAME(class_name)\
const Field_Node* class_name::GetSubClassFieldNode()const{\
typedef class_name thisClass;\
static const Field_Node thisClass##Field_Node[]={\
//结束宏
#define END_REGISTER_FILEDS_NAME()\
{TEXT(""),TEXT(""),0,0}};return &thisClass##Field_Node[0];}//添加字段信息结构宏
#define ADD_FIELD_NAME(fName,fType)\
{TEXT(#fName),TEXT(#fType),typeid(fType).hash_code(),(size_t)&((thisClass*)0)->fName},\

//TEXT(#fName) 字段名称(变量的名称,name,sex)
//TEXT(#fType) 数据类型名称(int ,bool)
//(size_t)&((thisClass*)0)->fName 字段的偏移量
//typeid(fType).hash_code() 获得数据类型的哈希值,用来比较数据类型是否相同

4.用法就更加简单了,

class Student :public QOBject{
REGISTER_CLASS_NAME()
public:Student(){}~Student(){}
public:int id;CString name;CString sex;UINT age;
};BEGIN_REGISTER_FILEDS_NAME(Student)ADD_FIELD_NAME(id, int)ADD_FIELD_NAME(name, CString)ADD_FIELD_NAME(sex, CString)ADD_FIELD_NAME(age, UINT)
END_REGISTER_FILEDS_NAME()//测试函数中//通过父类的静态方法获取子类New的对象
//用父类指针来操作子类对象进行赋值,获取值等操作
QOject* pObj=QObject::CreateObject<Student>();//给对象赋值
pObj->Set_Value(TEXT("id"),123);
pObj->Set_Value(TEXT("name"),CString(TEXT("张三")));
pObj->Set_Value(TEXT("sex"),CString(TEXT("男")));
pObj->Set_Value(TEXT("id"),(UINT)33);//获取对象字段的值
Student s;
pObj->Get_Value(TEXT("id"),s.id);
pObj->Get_Value(TEXT("name"),s.name);
pObj->Get_Value(TEXT("sex"),s.sex);
pObj->Get_Value(TEXT("id"),s.age);//最后操作完可转化子类对象指针
Student *pStu=(Student*)pObj;

总结一下是不是比前面[写的简单多了,也容易弄懂,
其实关键是获取子类的结构信息,用纯虚函数就能调用子类的静态字段结构数组,
也就相对简单了,

相关文章:

C++类对象反制机制实现_精简修改版

前几天写的类对象反射机制太烦锁了,今天写个修改版的,精简为两个类 一个是类的数据结构,另一个是类的父类对象,把所有操作类的方法都写到父类中 1.类的信息结构体 struct Field_Node {TCHAR m_name[20]; //字段名称TCHAR m_typeName[20]; // 字段类型名称size_t m_typeHashC…...

C#开发的IEnumerable接口

C#开发的IEnumerable接口 在前面分析中,我们会遇到下面这行代码: var refineries = self.World.ActorsWithTrait<IAcceptResources>() .Where(r => r.Actor != ignore && r.Actor.Owner == self.Owner && IsAcceptableProcType(r.Actor)) .Select…...

Redis详细安装教程

目录 一、Redis 的安装及启动停止1-1 下载 redis的压缩包1-2 开始解压 redis1-3 执行 make 命令编译1-4 启动 redis修改配置文件1-5 设置远程连接1-6 设置后台启动1-7 设置密码1-8 配置服务启动&#xff08;使用 systemctl 的方法&#xff09;启动 redis配置开机启动操作redis使…...

36基于matlab的对分解层数和惩罚因子进行优化

基于matlab的对分解层数和惩罚因子进行优化。蚁狮优化算法优化VMD,算术优化算法优化VMD&#xff0c;遗传优化算法优化VMD&#xff0c;灰狼优化算法优化VMD&#xff0c;海洋捕食者优化算法优化VMD&#xff0c;粒子群优化VMD&#xff0c;麻雀优化算法优化VMD&#xff0c;鲸鱼优化…...

【Flutter】自定义分段选择器Slider

【Flutter】ZFJ自定义分段选择器Slider 前言 在开发一个APP的时候&#xff0c;需要用到一个分段选择器&#xff0c;系统的不满足就自己自定义了一个&#xff1b; 可以自定义节点的数量、自定义节点的大小、自定义滑竿的粗细&#xff0c;自定义气泡的有无等等… 基本上满足你…...

【软考系统架构设计师】2023年系统架构师冲刺模拟习题之《软件工程》

在软考中软件工程模块主要包含以下考点&#xff1a; 文章目录 软件过程模型&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;逆向工程&#x1f31f;基于构件的软件工程&#x1f31f;&#x1f31f;软件开发与软件设计与维护净室软件工程软件模型软件需求 软件过程模型&am…...

非遗主题网站的设计与实现基于PHP实现

包括源码参考论文 下载地址: https://juzhendongli.store/commodity/details/18...

YOLO目标检测——红外人员数据集【含对应voc、coco和yolo三种格式标签+划分脚本】

实际项目应用&#xff1a;红外热像仪进行安全监控数据集说明&#xff1a;红外人员检测数据集&#xff0c;真实场景的高质量图片数据标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yolo(txt)三种格式标签&#xff…...

C++项目——云备份-⑧-客户端各模块实现

文章目录 专栏导读1.客户端数据管理模块实现2.客户端文件检测模块实现3.客户端文件备份模块设计4.客户端文件备份模块实现 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计划导师&#xff0c;阿…...

分享一款基于 AI 的 Chrome 插件

最近使用大模型比较多&#xff0c;公司虽然提供了免费的 ChatGPT 但是需要跳转特定页面才能访问&#xff0c;比较麻烦&#xff0c;于是就想到是否可以开发一款类似于有道词典一样的 Chrome 插件&#xff0c;可以在任意页面使用&#xff0c;虽然市面上也有类似的插件&#xff0c…...

Spring Authorization Server 1.1 扩展实现 OAuth2 密码模式与 Spring Cloud 的整合实战

目录 前言无图无真相创建数据库授权服务器maven 依赖application.yml授权服务器配置AuthorizationServierConfigDefaultSecutiryConfig 密码模式扩展PasswordAuthenticationTokenPasswordAuthenticationConverterPasswordAuthenticationProvider JWT 自定义字段自定义认证响应认…...

第二证券:AIGC概念活跃,焦点科技、三维通信涨停,万兴科技大涨

AIGC概念24日盘中走势生动&#xff0c;到发稿&#xff0c;万兴科技、三态股份涨超10%&#xff0c;焦点科技、三维通讯、我国科传等涨停&#xff0c;中文在线涨超9%&#xff0c;果麦文明、新国都涨约7%。 消息面上&#xff0c;各大电商途径于10月18-24日先后发动“双11”大促或…...

7-4、S加减速转动实现【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍实现步进电机S曲线运动的代码 一、目标功能 实现步进电机转动总角度720&#xff0c;其中加减速各90 加速段&#xff1a;加速类型&#xff1a;S曲线   加速角度&#xff1a;角度为90   起步速度&#xff1a;30RPM&#xff0c;   终止速度&#x…...

RK3568-pcie接口

pcie接口与sata接口 pcie总线pcie总线pcie控制器sata控制器nvme设备sata设备nvme协议ahci协议m-key接口b-key接口RC模式和EP模式 RC和EP分别对应主模式和从模式,普通的PCI RC主模式可以用于连接PCI-E以太网芯片或PCI-E的硬盘等外设。 RC模式使用外设一般都有LINUX驱动程序,安…...

spring监听请求执行结束,移除当前ThreadLocal数据两种方法

在开发过程中&#xff0c;很多时候我们会使用ThreadLocal来临时缓存数据&#xff0c;当一次数据请求执行完成后需要主动执行释放当前ThreadLocal缓存数据资源&#xff0c;防止未能及时释放导致下一次访问时候ThreadLocal依然保持上一次缓存的数据。 spring提供两种方式去监听一…...

知识图谱--Jena基础操作和检索推理应用

在上一篇读书笔记中讲到知识图谱存储主要有基于开源的Jena方式和基于图数据库(Neo4j)方式,本次主要对Jena的基础操作和如何应用进行了实践总结,同时结合了D2R,将结构化数据转换成Jena可以加载的格式(即RDF,后缀是.nt),Apache Jena作为一种开源的Java语义网框架,主要功…...

GEE python——将GEE ASSETS中存储的影像或者矢量转化为数据格式XEE()

数据转换器是内置于 getPixels、computePixels、listFeatures 和 computeFeatures 中的客户端转换能力。通过指定兼容的文件格式,这些方法可以返回 Python 原生格式的数据,如用于栅格的结构化 NumPy 数组和用于矢量的 Pandas DataFrames 或 GeoPandas GeoDataFrames。对于矢量…...

Java集合框架:List、Set、Map类型及泛型详解

文章目录 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。&#x1f30e;跑过十五…...

Ubuntu 安装 docker

一.添加Docker官方GPG密钥 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - 如果出现&#xff1a; The program curl is currently not installed. You can install it by typing: sudo apt install curl 先安装 curl : sudo apt inst…...

BUUCTF zip伪加密 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;得到一个zip压缩包。 密文&#xff1a; 解题思路&#xff1a; 1、刚开始尝试解压&#xff0c;看到了flag.txt文件&#xff0c;但需要解压密码。结合题目&#xff0c;确认这是zip伪加密&#…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...