备忘记录下来。
代码是从https://blog.youkuaiyun.com/scythe666/article/details/51718864抠出来的。
引用的另外一篇博客的地址:https://blog.youkuaiyun.com/cen616899547/article/details/9317323。但是这篇博客不是最原始地址,原始地址在博客里有描述 “ Published on 2012 年 2 月 28 日, by Eddy in C/C++, iOS技术 ”,不知道URL是什么。
代码如下:
宏定义REGISTER解读:
这个宏做了两件事情,
第一件事情是声明了一个函数,即 className* objectCreator##className();
声明的这个函数,每有一个类需要注册,就会配套着有一个new出待注册类的函数。这些个函数有一致的格式:
无参数,返回类型为该类的指针(可以强转为void*)。
第二件事情是声明了一个对象,即 RegisterAction g_creatorRegister##className(xxx,yyy);
这个RegisterAction构造函数有两个参数,第一个参数string是类的名字,第二个参数PTRCreateObject
是一个函数指针,指向上面第一步声明的那个函数。
在做第二件事情时,也即RegisterAction的构造函数,会将它的两个参数分别当作key和value,插入到
ClassFactory::m_classMap当中,这也就是ClassFactory::getInstance().registClass(className, ptrCreateFn);
这句代码的真正用途。
当然啦,第二件事情声明的这个对象是位于静态存储区的,它会在main函数之前就被构造出来。
#include <map>
#include <iostream>
#include <string>
using namespace std;
typedef void* (*PTRCreateObject)(void);
class ClassFactory {
private:
map<string, PTRCreateObject> m_classMap;
ClassFactory() {}; //构造函数私有化
public:
void* getClassByName(string className);
void registClass(string name, PTRCreateObject method);
static ClassFactory& getInstance();
};
void* ClassFactory::getClassByName(string className) {
map<string, PTRCreateObject>::const_iterator iter;
iter = m_classMap.find(className);
if (iter == m_classMap.end())
return NULL;
else
return iter->second();//返回的是PTRCreateObject类型的函数指针,可以转化为void*
}
void ClassFactory::registClass(string name, PTRCreateObject method) {
m_classMap.insert(pair<string, PTRCreateObject>(name, method));
}
ClassFactory& ClassFactory::getInstance() {
static ClassFactory sLo_factory;
return sLo_factory;
}
class RegisterAction {
public:
RegisterAction(string className, PTRCreateObject ptrCreateFn) {
ClassFactory::getInstance().registClass(className, ptrCreateFn);
}
};
#define REGISTER(className) \
className* objectCreator##className(){ \
return new className; \
} \
RegisterAction g_creatorRegister##className( \
#className,(PTRCreateObject)objectCreator##className)
//test class
class TestClass {
public:
void m_print() {
cout << "hello TestClass" << endl;
};
};
REGISTER(TestClass);
void test_register_class()
{
TestClass* ptrObj = (TestClass*)ClassFactory::getInstance().getClassByName("TestClass");
ptrObj->m_print();
return ;
}