所需工具:g++编译器 前言: 本文主要探讨并实现了如何用C++实现类似于.NET & JAVA的反射机制。 探讨: 近由于项目需求,我们需要用C++编写一个脚本执行程序(简而言之,是编写一个脚本执行框架)。但是很不幸的是,C++中并没有一种想相关的机制来仅仅通过一串函数名的字符串来对应执行函数(反射机制)。 举个实际的例子吧: 我现在有这么一个类: TestClassA{ Void func0(); Void func1(); }; 那么我希望在我的mian函数中如果出现 "TestClassA::func0"这样的字样的话 ,我能够通过某种方法真的执行这个函数(注意:不能再编写代码时写死哦~) 其实,C++中也不是真的不支持反射,比如C++11的RTTI中的typeid就有那么一点点萌芽~,但是很可以的是,RTTI的重点在于类型检查,而不是执行具体方法。 废话不多说了,开始正式思路探讨吧。 思路: 我研究了一下JAVA的反射,他们是这样用的 Foo foo = new Foo("这个一个Foo对象!"); Class clazz = foo.getClass(); Method m1 = clazz.getDeclaredMethod("outInfo"); Method m2 = clazz.getDeclaredMethod("setMsg", String.class); Method m3 = clazz.getDeclaredMethod("getMsg"); m1.invoke(foo); m2.invoke(foo, "重新设置msg信息!"); String msg = (String) m3.invoke(foo); System.out.println(msg); (引用地址:http://lavasoft.blog.51cto.com/62575/61002/) 那么我觉得JAVA编译器在编译过程中肯定是对Foo类中的各种成员函数进行了序列化,并把它放到了一个容器中。当我们要反射时,便会从这个容器中去除对应函数的函数指针然后通过回调函数执行。 那么我们的思路应该是: 0 定义一个函数指针,该函数指针应该与我们要反射的函数同类型。 1 创建以一个反射类,该类负责序列化自写类中的方法,并将其放入一个map容器中 2 在main函数运行前,将我们可能被反射的函数进行注册 代码: 0 定义函数指针(当然我们的函数也要写成这样子的) typedef void (TestClassA::*PTRDeclareFunc)(int,int); 1 定义反射类 注意:反射类应该是单例模式;应该有一个静态方法来反射;应该有一个方法来注册; class ReflectAction{ private: mapm_classFuncMap; ReflectAction(){} public: //============================================= static ReflectAction& getFuncInstance(); void getClassFuncByName(string className,int a,int b) { map ::const_iterator iter; iter = m_classFuncMap.find(className) ; if ( iter == m_classFuncMap.end() ) return; else { TestClassA *q = new TestClassA; PTRDeclareFunc p = iter->second; (q->*p)(a,b); } return ; } //============================================= void registClassFunc(string name, PTRDeclareFunc method) { m_classFuncMap.insert(pair (name, method)) ; } }; ReflectAction& ReflectAction::getFuncInstance(){ static ReflectAction sigleClass; return sigleClass;} 2 为我们书写的类进行注册 (我们用宏的方式来代替手动书写,这样比较节省书写时间) 注意:__attribute((constructor))该关键字指该函数在main函数执行前运行 #define REGISTER(className,funcName) __attribute((constructor)) void before_main##className##funcName() { ReflectAction::getFuncInstance().registClassFunc(#className#funcName,className::funcName); } 使用方法是: REGISTER(TestClassA,m_func); 3 我们自己的类是: class TestClassA{ public: void m_func(int a,int b); }; void TestClassA::m_func(int a,int b){ cout<<"hello TestClassA" << a << b <
世上所有的幸福闻起来,都是努力的味道1人生没有对错,只有选择后的坚持,不后悔,走下去,就是对的。走着走着,花就开了!2人这一生,会遇见不同的人,有的人,成了朋友有的人,成了过客。有的人,能陪一生有的人,只陪一程。不管教练组傲慢与自信的代价,澳门王曼昱和陈梦被爆冷的根源巴黎奥运女单热门人选陈梦和王曼昱接连被外协击败,引起了世界乒坛的轰动,这两个人可是世界上水平最高的运动员,最重要的是击败她两的是以前我们不削一顾的欧洲选手!生于忧患死于安乐,教练组郭艾伦被罚后续更新,辽篮内部表态新决定,郭少为冲动付出代价眼下CBA比赛进行的如火如荼,在最近一场比赛中,郭艾伦的缺席导致辽宁队输给山西队。在这次比赛输掉之后,很多球迷不禁想起之前郭艾伦因为私自外出被罚款的问题。当时CBA判定郭艾伦违反规一条藕池河里的鱼(外一首)作者山远风来那一天藕池河水可怕地萎缩了长江向东流向更低的城陵矶流去洞庭湖无奈地蜷缩到了湘江村口旁边的深潭在夜里被抽干了一条身体里面含有十多斤水分的鳡鱼放弃了徒劳的挣扎张了张嘴上岸没一心一意做个善良的自己1红尘一遭,懂你的人不用解释,不懂你的人不必解释。一心一意做个善良的自己,即使不完美,也是最好的。2只有频率相同的人,才能看见彼此内心深处不为人知的优雅懂得你的言外之意,理解你的山散文人生三件宝,健康善良和真情,愿你都拥有,吉祥安康人生有三样东西最无价,拥有了就是贵人,你的健康,你的善良,你的真情,都是无价之宝,是人生宝贵的财富,让我们一生都富贵,让生活充满幸福和温暖。一健康健康是我们人的一项基本权利,健康是道德存在于善恶之间,一念之间一个人如果没有道德的约束社会将成为什么样子?人性本恶。除了亲情,人性本身就是自私自利,懒惰阴险恶毒,卑鄙无耻全是兽性人为了生存,只能抱团取暖,形成了社会团体,自然就产生了礼教,形成善良何其珍贵,请别错付在网上看过一句话,颇为戳心容易受伤的,永远都是那些天真又心软的人,毕竟好骗又好欺,伤疤一好,就忘了疼。心软的人大多不爱争抢,别人一打苦情牌,他们就招架不住。即使自己受了伤,只要对方有钱可以治愈一切自卑,光善良没用,你要优秀爹有娘有,不好意思开口,公有婆有,伸手不一定有,夫有妻有,还隔了一手,千有万有,都不如自己有,任何人的底气都来自于经济实力,有钱可以治愈一切自卑心理,光善良没用,你要优秀!自己动手善良是一种修行,但过度的善良就是一种愚蠢有这样一句话世间所有的毒药和良药,都只是剂量上的不同。世间万物都有自己的生存法则,在做人做事的时候都要讲究一个度凡有度者做事才会有分寸,凡有度者才会对万物有敬畏之心。再善良的人做事王曼昱爆冷淘汰,前国乒世界冠军说出心里话,鳗鱼输了很正常眼下澳门冠军赛正在进行中,国乒爆出巨大的冷门。在最近进行的首场比赛,王曼昱面对法国选手老将居然不敌对手23爆冷出局。在赛前大家都以为王曼昱作为种子选手又是现在的世界第三,不管怎么样