反射其实就是把创建类的方法和类的字符串名字(当然也可以是相关的信息)绑定起来,这样就可以通过输入的字符串创建对应的类。
闲话少说,上代码:
【基类:Animal】
头文件:
#pragma once
class Animal
{
public:
Animal(){};
virtual ~Animal(){};
public:
virtual void test();
};
typedef Animal* (*funCreateAnimal)();
源文件:
#include "Animal.h"
#include <iostream>
using namespace std;
void Animal::test()
{
cout << "Animal" << endl;
char ch;
cin >> ch;
}
【注册用的工厂类:Zoo】
头文件:
#pragma once
#include "Animal.h"
#include <string>
#include <map>
using namespace std;
// 注册宏
#define DECLARE_REGISTER(class_name) \
public: \
static bool s_bRegisterFlag; \
static Animal* CreateInstance() {return new class_name();}
#define IMPLEMENT_REGISTER(name, class_name) \
bool class_name::s_bRegisterFlag = \
Zoo::CreateInstance()->RegisterAnimal(name, class_name::CreateInstance);
class Zoo
{
private:
map<string, funCreateAnimal>* s_AnimalMap;
public:
Zoo(){s_AnimalMap = NULL;}
~Zoo(){}
public:
bool RegisterAnimal(string name, funCreateAnimal fun);
Animal* CreateAnimal(string name);
public:
static Zoo* CreateInstance();
};
源文件:
#include "Zoo.h"
Zoo* Zoo::CreateInstance()
{
static Zoo* instance = new Zoo();
return instance;
}
bool Zoo::RegisterAnimal(string name, funCreateAnimal fun)
{
if (s_AnimalMap == NULL)
{
s_AnimalMap = new map<string, funCreateAnimal>();
}
if (name == "")
{
return false;
}
if (s_AnimalMap->find(name) == s_AnimalMap->end())
{
s_AnimalMap->insert(pair<string, funCreateAnimal>(name, fun));
}
return true;
}
Animal* Zoo::CreateAnimal(string name)
{
map<string, funCreateAnimal>::const_iterator iter = s_AnimalMap->find(name);
if (iter != s_AnimalMap->end())
{
funCreateAnimal fun = iter->second;
return fun();
}
return NULL;
}
【子类:Cat】
头文件:
#pragma once
#include "Animal.h"
#include "Zoo.h"
class Cat :
public Animal
{
DECLARE_REGISTER(Cat)
public:
void test();
};
源文件:
#include "Cat.h"
#include <iostream>
using namespace std;
IMPLEMENT_REGISTER("Cat", Cat)
void Cat::test(void)
{
cout << "喵喵~~" << endl;
char ch;
cin >> ch;
}
【测试函数】
#include "Animal.h"
#include "Zoo.h"
int main()
{
Zoo* pZoo = Zoo::CreateInstance();
Animal *animal = NULL;
animal = pZoo->CreateAnimal("Cat");
animal->test();
delete animal;
animal = NULL;
delete pZoo;
pZoo = NULL;
}