一种实现C++反射功能的想法(一)
Java的反射机制很酷, 只需知道类的名字就能够加载调用. 这个功能很实用, 想象一下, 用户只需指定类的名称, 就可以动态绑定类型, 而且只需通过字符串指定, 字符串的使用可以使得用户的修改只需修改一个配置文件就行, 仅仅修改配置文件, 连重新编译都不需要. 喔噢噢, 这种做法将代码的解耦程度做到了极致, 这种技术也不是什么新技术, spring, struct, hibernate......大多数框架都使用到java的反射机制, 而且是作为核心技术, 如果你还未了解反射的话, 赶紧抓紧时间吧.
有这么一句话, "机器码生汇编, 汇编生C, C生万物...". 同为重量级的编程语言的C/C++有没有类似的反射机制呢? 很遗憾, C++的语法并没有. 首先, 让我们先整理一下C++ 跟 java的区别:
我对java不熟悉, 所以我大致是这样理解java 实现反射的机制: jvm 在解释执行.class文件时, 遇到了使用反射的字节码, 于是类加载器加载相应的.class, jvm跳到特定的地方继续执行.如果有错误, 还请大家指正. 而C++不同, C++将源程序直接编译成可执行文件, 一般这个可执行文件是不可改变的. 一旦编译完成后, 想要再修改程序, 就必须重新编译.
那么C++能不能实现类似java的反射呢? 这是个很有吸引力的问题, 大把大把的人在探索解决方案.
(一) 从根本上解决就是修改编译器, 当编译器扫描到使用反射的语句时生成特定的机器码, 程序执行时能正确跳跃到相应的位置. 听起来跟java原理很像, 还是有点区别的. 这个方案需要解决两个问题, 一是类的序列化问题, 二是编译器的问题. 这两个都不是简单的问题.
(二) 或许我们将标准放低一点, 实现伪反射就行. 从编程角度上解决问题, 这是比较现实的做法, 不少人提出了各式各样的解决方案:
1. 使用map 将类名跟类产生器对应起来, 类扩展通过动态链接库来做, 缺点是扩展时必须重新链接, 不过相对于重新编译已经提高了一个层次.
2. 使用类似注解的方法, 编译的时候先将注解的地方换成C++语句, 在调用C++编译器编译. 缺点是不能做扩展, 扩展必须重新编译.
我的做法也是对上面两种方法的小修小部而已, 不过我还实现了函数的反射功能, 先上demo
类类型:
class Sharp { public:
virtual void say() = ; }; class Point: public Sharp { public:
virtual void say();
}; class Line: public Sharp { public:
virtual void say();
}; class Init { public:
void declation(const char* arg);
}; void Point::say() { std::cout<<"Point\n"<<std::endl;
}
REGIST(Point) void Line::say() { std::cout<<"Line\n"<<std::endl;
}
REGIST(Line) void Init::declation(const char* arg) { std::cout<<"demo"<<std::endl;
std::cout<<"Argument: "<<arg<<std::endl;
}
REGIST(Init)
配置文件
<Configure>
<Function name="declation" scale="Init">
<Argument></Argument>
</Function> <Bean name="Sharp" reference="Line" />
</Configure>
程序
int main() { BeanFactory::sharedFactory().setContextEnv("context.xml");
BeanFactory::sharedFactory().configure("configure.xml"); Sharp* s = static_cast<Sharp*>(BeanFactory::sharedFactory().getBeanByName("Sharp"));
s->say();
}
运行结果:
结果跟预期的一样, 在下一篇中我将介绍我实现的方法
一种实现C++反射功能的想法(一)的更多相关文章
- 一种实现C++反射功能的想法(三)
如何实现类型名跟类型的对应, 我们很容易想到map, 没错, 就是使用map实现的. std::map<std::string, .....>, 等下, 第二部分该填什么类型, 一个函数指 ...
- 一种实现C++反射功能的想法(二)
在介绍我的思路前, 让我们准备下预备知识 C++是怎么实现类函数的绑定的. 我们知道类的非静态成员函数是存储在全局区, 并在内存中只保存一份副本. 我们调用非静态成员函数是通过类对象进行调用. 那么如 ...
- 使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法
使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法 效果展示 一个很简单的组件脚本 运行状态在Inspector面板可以随便修改字段和调用方法 方法调用日志 设计由来 最近在 ...
- asp.net导出excel-一行代码实现excel、xml、pdf、word、html、csv等7种格式文件导出功能而且美观-SNF快速开发平台
分享: 腾讯微博 新浪微博 搜狐微博 网易微博 腾讯朋友 百度贴吧 豆瓣 QQ好友 人人网 作者:王春天 原文地址:http://www.cnblogs.com/spring_ ...
- Java反射获取class对象的三种方式,反射创建对象的两种方式
Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...
- 设计模式之抽象工厂模式(附带类似反射功能的实现/c++)
问题描述 假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理).于是我们就可以采用这样一 ...
- 在c++中实现反射的初步想法
最近在思考如何在c++中实现反射.事情的起因是这样的:我们服务器是用c++开发的,如果需要写一些测试用的GM指令的话,需要编写完GM代码后重新编译并且重启进程,工序繁琐且比较耗时.因此就有了想用脚本( ...
- 单例模式的几种实现And反射对其的破坏
一 单例模式概述 (一) 什么是单例模式 单例模式属于创建型模式之一,它提供了一种创建对象的最佳方式 在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象.基本的对 ...
- 几种常用的bootstrap功能。
---恢复内容开始--- 我对于bootstrap定义与一种插件,他可以使我们的网页布局更加的炫酷,更加的整洁和合理.他的优点不多说,缺点一个就够我们头疼的,那就是需要记一些长长的英文名. 我为大家说 ...
随机推荐
- BZOJ 1053 [HAOI2007]反素数ant
1053: [HAOI2007]反素数ant Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1948 Solved: 1094[Submit][St ...
- Java---JUnita、注解与类加载器详解以及实例
JUnit软件测试技术(工具) 在项目中建立专门用户测试的包结构. 在Junit中,通过@Test注解,可以运行一个方法. ★ Junit注解说明 使用了@Test注解应该满足以下条件: 1) 必须是 ...
- POJ1182 食物链(并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 55260 Accepted: 16210 Description ...
- 网络协议- HTTP
http:是用于www浏览的一个协议.tcp:是机器之间建立连接用的到的一个协议.
- getting start with storm 翻译 第八章 part-1
转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/12434915 第八章 事务性Topologies 在Storm中,正如本书前边 ...
- flumeng-kafka-plugin
github 参考地址:https://github.com/beyondj2ee/flumeng-kafka-plugin/tree/master/flumeng-kafka-plugin /* * ...
- ionic2 干货
亲爱的程序员童鞋 分享干货啦 最近在研究ionic2 ,公司也在用ionic2 和typescript,angular2以及cordova做混编APP 我的博客随笔都是随性写的,做了某个功能就想分享一 ...
- CKEditor&ckfindtor
前言 之前的项目中一直使用的是FCKeditor,昨天突然有个想法:为什么不试一下新的CKEditor呢?于是花了大半天的时间去学习它的使用方法,如今把我的学习过程与大家分享一下. 谈起FCKedit ...
- 用PHP迭代器来实现一个斐波纳契数列(转)
斐波纳契数列通常做法是用递归实现,当然还有其它的方法.这里现学现卖,用PHP的迭代器来实现一个斐波纳契数列,几乎没有什么难度,只是把类里的next()方法重写了一次.注释已经写到代码中,也是相当好理解 ...
- win7 32/64bit VS2010 OpenCV 2.4.9 环境配置
作者 : 卿笃军 因为近期人脸识别须要用到OpenCV,让我開始了OpenCV学习. OpenCV 2.4.9下载地址:http://sourceforge.net/projects/opencvli ...