c++实现反射机制(两篇)

                                                 第一篇

C++ 编程语言是一款功能强大的计算机应用语言。其能够支持很多程序设计风格。我们今天将会在这里为大家详细介绍一下有关C++反射机制的具体实现步骤,大家可以从中获得一些有帮助的内容。

在Java编程中,我们经常要用到反射,通过反射机制实现在配置文件中的灵活配置, 但在C++编程中,对这种方式步提供现有的支持,那么我们怎么才能在配置文件中配置想要调用的对象呢? 

我们的思路是通过对象名称确定对象实例,把对象名和对象实例通过哈希表进行映射,那么我们就可以实现通过对象名称获取对象了。首先定义一个C++反射机制的结构:

 

    
    typedef DynBase* (funCreateObject)();
    struct ClassInfo  
    {  
    public:  
    string Type;  
    funCreateObject Fun;  
    ClassInfo(string type, funCreateObject fun)  
    {  
        Type = type;  
        Fun = fun;  
        DynBase::Register(this);  
    }  

 

其中Register这样定义

  1. bool Register(ClassInfo* ci);

 

然后定义一个类,头文件如下:

    class AFX_EXT_CLASS DynBase   
    {  
    public:  
    DynBase();  
    virtual ~DynBase();  
    public:   
    static bool Register(ClassInfo* classInfo);  
    static DynBase* CreateObject(string type);  
    private:   
    static std::map<string,ClassInfo*> m_classInfoMap;  
    }; 

cpp文件如下:

    std::map< string,ClassInfo*> DynBase::m_classInfoMap = 
    std::map< string,ClassInfo*>();  
    DynBase::DynBase()  
    {  
    }  
    DynBase::~DynBase()  
    {  
    }  
    bool DynBase::Register(ClassInfo* classInfo)  
    {   
        m_classInfoMap[classInfo->Type] = classInfo;   
        return true;   
    }  
    DynBase* DynBase::CreateObject(string type)  
    {  
    if ( m_classInfoMap[type] != NULL )   
    {   
    return m_classInfoMap[type]->Fun();  
    }  
    return NULL;  
    } 

 那么我们在C++反射机制的操作中实现映射的类只要继承于DynBase就可以了,比如由一个类CIndustryOperate

头文件如下:

    class CIndustryOperate : public DynBase  
    {  
    public:  
    CIndustryOperate();  
    virtual ~CIndustryOperate();  
    static DynBase* CreateObject(){return new CIndustryOperate();}  
    private:  
    static ClassInfo* m_cInfo;  
    }; 

cpp文件如下:

    ClassInfo* CIndustryOperate::m_cInfo = 
         new ClassInfo("IndustryOperate",(funCreateObject)( CIndustryOperate::CreateObject));  
    CIndustryOperate::CIndustryOperate()  
    {  
    }  
    CIndustryOperate::~CIndustryOperate()  
    {  
    } 

 

                                                                        第二篇

       C++语言本身不支持反射机制,但C++对象总是要序列化的,序列化就是存储到磁盘上,将对象变成一定格式的二进制编码,然后要用的时候再将保存在磁盘上 的二进制编码转化成一个内存中的对象,这个过程中总是需要有一个指示来告诉编译器要生成什么样的对象,最简单的方式当然就是类名了,例如:将一个 ClassXXX对象存储到磁盘上,再从磁盘读取的时候让编译器根据“ClassXXX”名称来new一个对象。
但是问题出现了,C++语言本身不支持反射,也就是说不能通过如下方式生成一个对象:
ClassXXX object = new “ClassXXX”;

工厂方法
当然,这样的方法不行,那我们只有另辟蹊径。最简单的就是工厂方法了:
ClassXXX* object = FactoryCreate(“ClassXXX”);
至于FactoryCreate的设计就很简单了,if的集合就可以了:
if(name = “ClassXXX”)
return new ClassXXX;
if(name = “ClassYYY”)
return new ClassYYY;

看起来不错,来个类名就可以生成对应的对象,功能上解决了根据类名生成对象的问题。
假 如以上所有的代码都有你一个人编写,那当然问题不大,但是假如有一天你的公司扩大了,这部分代码由两个不同的组A和B来维护,啊哈,问题来了,A组每添加 或者修改一个类,都要通知B组更新FactoryCreate函数,也就是说A组的任何关于类的修改,都需要B组来修改,但实际上B的修改不产生任何价 值,而且不胜其烦,永无止尽!!如果哪天来了一个新员工,由于对这个规定还不清楚,忘记了通知,那就完了:编译通不过!
一个公司内都会产生如此多的问题,更何况微软这样的大公司是面对全球的各种各样的客户,如果微软把这部分做进框架代码中,呵呵,那微软所有的人不用干其他事情了,每天处理来自全球的要求修改FactoryCreate函数的邮件和电话就够他们忙的了:)

回调工厂
既然此路不好走,那么我们再考虑其它方法吧,一个可选的方法是将FactoryCreate做成回调函数,框架提供注册接口RegisterFactoryCreate,框架函数如此实现:
typedef CObject* (*FactoryCreate_PTR)(String name);
RegisterFactoryCreate(FactoryCreate_PTR fc_ptr);
应用代码如此实现:
CObject* MyFactoryCreate(String name);
RegisterFactoryCreate(MyFactoryCreate);
到这里一个框架和应用分离的反射机制基本实现了,你是否长吁一口气,然后准备泡杯咖啡,稍微放松一下呢?确实可以稍微休息一下了,毕竟我们完成了一件非常了不起的事情,让C++实现了反射。

但你只悠闲了一两天,麻烦事就来了。员工张三跑来向你抱怨“老大,李四注册的反射函数把我的覆盖了”!哦,你仔细一看,My god,这个注册函数只能注册一个反射函数,后注册的就把前面的覆盖了!
怎么办?总不可能又要求所有的类的反射函数都在一个工厂里实现吧,那这样就又回到了工厂方法中描述的时代了。
当然,聪明的你估计很快就能想出问题的解决方法,将RegisterFactoryCreate函数稍加修改就能满足要求了,新的实现如下:
RegisterFactoryCreate(FactoryCreate_PTR fc_ptr,String className)
然后要求每个类都单独写自己的FactoryCreate_PTR函数,类似如下方式:
static CObject* ClassXXX::CreateClassXXX (){
       return new ClassXXX;
};

static CObject* ClassYYY::CreateClassYYY(){
       return new ClassYYY;
};

到此为此终于大功告成,通过我们的智慧实现了C++的反射功能!一股自豪感油然升起:)

最后的杀手锏:宏
当你为自己的聪明才智而骄傲的时候,那边却有几个开发的兄弟在发出抱怨“唉,这么多相似的函数,看着都眼花,每个类都要写,烦死了”。
或者有一天,你要在每个类的CreateClass函数中增加一个其它功能(例如日志),那么开发的兄弟真的是要烦“死了”!!!

其实仔细一看,包括函数申明、函数定义、函数注册,每个类的代码除了类名外其它都是一模一样的,有没有简单的方法呢?
肯定是有的,这个方法就是宏了,按照如下方法定义宏:
#define DECLARE_CLASS_CREATE(class_name) \
static CObject* CreateClass## class_name ();

#define IMPL_CLASS_CREATE(class_name) \
static CObject* CreateClass## class_name (){  \
       return new class_name;             \
};

#define REG_CLASS_CREATE(class_name) \
RegisterFactoryCreate(class_name::CreateClass## class_name, #class_name);
注:##是连接符,将两个字符串连接起来,#是将class_name作为字符串处理。

大家可以比较一下,用了宏和不用宏是不是代码感觉完全不一样呢?而且那天需要增加一个简单的功能,只需要改宏定义就ok了,不要全文搜索所有相关函数,然后一个一个的重复添加。

到这里才真正是大功告成!!

 

 

 

 

 

 

 

C++反射机制 用c++实现的反射机制,只需继承该类,子类便可通过字符串来调用默认构造函数进行创建,这只是一个简单的原型,可扩展到其他带参数构造函数 立即下载

相关推荐

STM32 AFIO时钟开启时机与复用功能解析

在嵌入式系统开发中,GPIO复用是微控制器外设配置的核心技术之一。通过复用功能,单个物理引脚可以动态切换不同功能模式,如USART通信或普通IO。其实现原理依赖于芯片内部的时钟树架构和寄存器配置机制。AFIO(Alternate Function I/O)模块作为STM32的特色设计,专门处理引脚重映射、外部中断配置等高级功能。正确理解复用功能与AFIO时钟的关系,能显著提升嵌入式开发效率,避免资源浪费。本文以STM32为例,结合引脚重映射和USART配置等典型场景,详解AFIO时钟的实际应用规范与优化实践

weixin_42389113的博客 578

我所理解的 C++ 反射机制

在实际的项目中,听师兄说项目中用到了 C++ 反射,出于好奇,就查阅相关资料,发现强大的 C++ 本身并不支持反射,反而 Java 支持反射机制。当我得知这个事实时,唯 C++ 马首是瞻的我,心中暗自落泪,悲叹不已。但是,C++ 的拥趸们别难受,强大的 C++ 本身不支持,但却可以让我们手动实现,真的是曲径通幽处,禅房花木深。C++ 是不会辜负我们对它至死不渝的追逐。但是,说到 Java 的反射机制或者 C++ 用到了反射,如果没有真正的在项目中使用过,我们对它会感觉到陌生和不解。

Doublelv 的博客专栏。 3万+

【UV打印机】RYPC打印软件教程(二)-软件界面概述

下图是控制软件的主操作界面.将喷绘机的操作规纳为四块,分别为参数设置,任务选择,打印控制,系统维护,对于日常打印而言,只需操作任务选择,打印控制。从而使汲及的操作相对较少,使得系统对普通用户而言简单易用.

Print World的专栏 3598

C++反射机制的实现

前几天用C++为《捕鱼达人》移植UI编辑器的时候,遇到了几个难点。一个是通过类名的字符串创建相应的类的实例化。还有一个是通过属性的名字字符串来操作相应的类的属性。用支持反射的Objective-C或者Java语言来实现类似功能是非常简单的。但是C++不支持,纠结了几天,终于实现了类似于反射的功能。 思路分为以下几步: 1、在要反射的类中定义一个回调函数,用来创建这个类的实例; 2、设计一个工

flyingleo1981的专栏 1254

NRF52832调试方法1——HardFault_Handler问题定位

一、遇到问题 keil debug模式下,直接点击全速运行(Run)发现程序卡死,点击stop按钮后,停到了HardFault_Handler位置,如下图所示。 此时使用navigate backwards(蓝色左箭头)是无效的,找不到程序卡在哪里。 二、解决办法 此时首先观察register窗口 若Stack为MSP,则复制R13(SP)的值到memory观察窗的地址搜索栏。每一行显示连续的28个地址上的存储信息,每个地址上存有一个字节。 从第21个位置起的连续四个字节是LR的值,

小梁的博客 3650

wsl + vscode 离线配置 ERROR: Faild to download https://update.code.visualstudio.com

很多情况下是没有现成的VS Code Server程序的,需要手动下载。记住上面的Commit ID,可以通过下面的链接下载 vscode-server-linux-x64.tar.gz。然后将vscode-server-linux-x64.tar.gz上传在服务器上的$HOME/.vscode-server/bin文件夹中,解压。在wsl中下载不了 vscode 的核心。运行下面两行命令,建立空的$HOME/.vscode-server/bin文件夹。重新运行 wsl与vs的链接即可。

点云算法工程师 3789

C++ 实现反射机制

JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。然而C++是不支持反射机制,虽然C++有RTTI(运行时类型识别)。但是想要实现C++对象序列化,序列化就是存储到磁盘上,将对象变成一定格式的二进制编码,然后要用的时候再将保存在磁盘上的

YzlCoder的记事本 1万+

告别重打包:在Android 9上实现免Root的Frida-Gadget持久化Hook(附AOSP源码修改详解)

本文详细介绍了在Android 9上实现免Root的Frida-Gadget持久化Hook技术方案。通过修改AOSP源码,绕过传统重打包方式面临的签名校验和完整性检查,实现在非Root环境下的系统级Hook。文章包含核心代码修改、编译配置调整及调试技巧,为移动安全研究提供高效稳定的解决方案。

weixin_33726313的博客 501

c++实现反射机制

一、问题的提出 在c++程序中,如果知道了一个类,然后我们就可以使用类名去访问这个类的 静态公有成员变量 或 静态成员函数: 类名::静态公有成员变量; 类名::静态公有成员函数; 或者我们可以创建这个类的一个对象,然后通过对象去访问公有成员变量 或 公有成员函数: 类名 *pobj = new 类名(); pobj -> ...

akkk1kkka的博客 2490

Android Activity面试题最全解析(5万字长文)

Intent是Android中用于启动活动、服务或广播的一种消息对象。它包含了一系列键值对数据,用于描述操作的目的以及需要传递的信息。IntentString:字符串intfloatlong:基本数据类型Parcelable:实现了Parcelable接口的对象:实现了接口的对象示例代码如下:Java深色版本1// 创建Intent并传递数据");67// 启动新的Activity是一个XML标签,用于定义ActivityService或可以响应的Intent类型。它包含了。

大模型大数据攻城狮的专栏 801

22、自动化地图制作与Pandas数据处理

本文介绍了在ArcGIS Pro中使用arcpy.mp模块进行自动化地图制作的关键技术,涵盖地图元素的访问、移动与文本修改,以及将布局批量导出为JPEG、PNG和PDF格式的方法。同时,文章深入探讨了Pandas在数据处理和地理空间分析中的应用,特别是Spatially Enabled DataFrames(SEDFs)的使用。通过综合案例展示了地图更新与数据清洗、分析的结合,提升了地图制作与数据处理的效率,为GIS自动化工作流提供了实用指南。

w8x9y0z1的博客 78

yaml-cpp动态数据绑定终极指南:C++反射机制实现详解

yaml-cpp 是一个功能强大的 C++ YAML 解析器和发射器,它通过巧妙的**反射机制**实现了**动态数据绑定**功能,让开发者能够轻松处理YAML配置文件。作为遵循YAML 1.2规范的完整实现,yaml-cpp的**动态数据绑定**技术为C++开发者提供了前所未有的灵活性。 ## 🔍 什么是yaml-cpp反射机制? yaml-cpp的**反射机制**本质上是一种**类型转换系

gitblog_00007的博客 799

VSCode PlantUML 插件超详细教程:从安装配置到实战绘图全流程

VSCode PlantUML 插件超详细教程:从安装配置到实战绘图全流程

weixin_69237381的博客 907

C++ 实现反射机制(转载)

版权声明:本文为优快云博主「YzlCoder」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.youkuaiyun.com/y1196645376/article/details/51455273 前言 JAVA有着一个非常突出的动态相关机制Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括metho

xupeng1644的博客 3393

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

C++反射机制简单实现

一直以来,C++都未能支持反射机制,在C++中要实现类似Java等语言的反射机制需要另外写代码保存类型相关信息,然后在运行时使用。 C++引入了typeid运算符,可以在运行时获取类型相关信息,说明C++在编译时是会保存类型相关信息的,只是C++标准要求保存的运行时类型信息不足以支撑类似Java的反射机制。下面给出一个简单的例子,说明程序在运行时获取类型相关信息。 class Object ...

xungen的博客 1180

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++反射机制实现

Java中有反射机制,但是C++中并没有这种机制。如何动态的通过字符串创建相应的实例对象,就是利用了反射的一种方式。 1.首先需要把字符串标识和对应的创建函数保存起来,以方便可以通过相应字符串实现对象的创建。 #pragma once #include <map> #include <string> //类对象生成工程 //定义创建对象的函数指针 typedef voi...

wb175208的专栏 2504

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

《C++中的反射机制:开启高级编程之门》

如果没有反射机制,我们就需要通过一些复杂的技巧和技术来实现这些功能,这不仅增加了编程的难度,还降低了程序的可维护性和可扩展性。例如,Boost.Reflection 库就是一个强大的 C++反射库,它提供了丰富的功能和灵活的接口,可以方便地实现反射机制。在这些语言中,程序员可以通过反射机制轻松地获取对象的信息,并对其进行操作,而不需要在编译时就知道对象的具体类型。反射机制是指在程序运行时,能够动态地获取对象的信息(如类型、成员变量、成员函数等),并能够对这些信息进行操作的一种机制。

xy520521的博客 1564

探索CPP-Reflection:C++中的元编程魔法

在C++的世界里,元编程是一种强大的工具,它允许我们在编译时执行计算和生成代码。`CPP-Reflection`是由Austin Brunkhorst创建的一个开源库,它为C++引入了简单而直观的反射机制,使得开发者可以更容易地探索和操作程序的运行时信息。 ## 项目简介 `CPP-Reflection`是一个轻量级的库,它的核心目标是提供一种方式让C++代码能够自我描述,允许你在运行时检查类

gitblog_00084的博客 1106
上一篇: FuzzyQuery中计算edit distance的算法函数
下一篇: lucene提高搜索性能
eric509
博客等级 码龄19年 8粉丝 170原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值