引言:
我们知道C++,本身是没有反射库的。不像Java反射技术的运用渗透到语言的点点滴滴。发明C++的那些大佬们在设计之初并没有想到这一点(正如STL中没有Hash Table一样),但是这个也并不会阻止C++成为一门优秀的语言。我们懂得反射的原理之后我们也可以实现一个简单的反射技术。我在接下来的观点也仅仅是抛砖引玉,你们如果有好的意见,我们可以一起讨论一起进步!
我所理解的反射
程序员界有句话 反射反射程序员的快乐 (不押韵?没有事!这不重要)我们知道C++是面向对象(OO)的语言。我们说了半天可能还是有人不知道反射究竟有什么好处。面向对象的程序设计中,我们提倡的是 开放封闭原则:
软件的实体(类,模块,函数等)应该可以扩展,但是不可以修改。
用大白话说就是对于程序而言,我们对于扩展是开放的,而对于修改则是封闭的。我们在程序中肯定会遇到我们不得不写大量的 if else 和 switch case语句。当代码量上升到一个比较打的程度的时候我们会发现一个问题,我们在新增一个功能的时候会变得十分的困难我们不得不修改上面的那两个语句,这个时候反射就会让我们回避这个问题。
那么反射究竟是什么?C++是一门抽象的语言,我们将事物抽象成类,将各个事物之间的相互的关系抽象成一个方法。来模拟他的各种行为变化等。我们在C++中经常会说的一句话就是那里变化封装那里或者可以理解为那里不变的话,提炼出我们的对象的不变的部分,写成接口。同样对于上面那个问题我们遇到的难点是出现那里?函数名在不停的变化,使得我们也要不停地变化我们的判断结构来适应他的变化,如果我们可以抽象函数名,并给出一个接口我们就可以不用来修改代码了甚至于我们在新增功能的时候甚至于不用重新编译我们已经好的部分。
我们的设计流程
下面我们直接上代码吧
#include<iostream>
#include<map>
#include<string>
using namespace std;
//定义函数指针
typedef void (*create_fun)();
//反射表
map<string, create_fun> my_map;
//获取反射表
void GetFunByName(string name)
{
map<string, create_fun>::iterator it = my_map.find(name);
if (it == my_map.end()) return;
create_fun fun = it->second;
if (!fun) return;
fun(); return;
}
//注册函数
void registFun(string name, create_fun fun)
{
my_map[name] = fun;
}
void Test()
{
cout << "这是一个例子" << endl;
}
int main()
{
registFun("Test",Test);
GetFunByName("Test");
return 0;
}
输出:
这是一个反射的最基本的实现,但是足以让我们从中理解反射的技术的原理和他的编写方法了。我们后续会基于这个代码多次迭代尽量写出一个厉害的代码。