class_factory.h
#ifndef __CLASSFACTORY_
#define __CLASSFACTORY_
#include <iostream>
#include<string>
#include<map>
//定义函数指针
typedef void* (*create_fun)();
class ClassFactory{
public:
~ClassFactory() {};
//根据类注册时的名字, 创建类实例, 并返回
void* getClassByName(std::string name){
std::map<std::string, create_fun>::iterator it = my_map.find(name);
if (it == my_map.end()) { return NULL; }
create_fun fun = it->second;
if (!fun) { return NULL; }
return fun();
}
//注册类名称与指针函数到映射关系
void registClass(std::string name, create_fun fun){
my_map[name] = fun;
}
//单例模式
static ClassFactory& getInstance(){
static ClassFactory fac;
return fac;
}
private:
ClassFactory() {}; //私有
std::map<std::string, create_fun> my_map;
};
#endif
test.h
#ifndef __TEST_H
#define __TEST_H
#include <iostream>
class Test{
public:
Test(){ std::cout << "call Test Constructor fun" << std::endl; }
~Test(){ std::cout << "call Test Destructor fun" << std::endl; }
void print(){ std::cout << "call Test print fun" << std::endl; }
};
void* create_Test(){
Test *t = new Test;
return (t == NULL)? NULL:t;
}
#endif
main.cpp
#include "test.h"
#include "class_factory.h"
int main(){
//注册
ClassFactory::getInstance().registClass("Test", create_Test);
//获取类对象
Test *t = (Test*)ClassFactory::getInstance().getClassByName("Test");
if (!t){
std::cout << "get instnce Test err;" << std::endl;
return 1;
}
t->print();
delete t;
return 0;
}
Create C++ Object Dynamically
Introduction
C++不像C#和Java那样具有反射的能力,通常不能根据任意一个class name来创建该class的instance。但我们知道在MFC中,任何继承了CObject的类都可以根据其名字来创建实例,它是使用了一些宏。而我从来就不喜欢使用大把的宏,虽然有的时候宏可能比较方便,可能对某些人来说也更美观。
原理很简单——定义一个基类,维护一个其派生类信息(包括派生类的名字和创建实例的函数指针)的列表,而派生类在程序运行的最初始阶段就向基类注册其信息。
Design & Implementation
Base Class—— DynBase
Derived Class—— Any Class Derived from DynBase
DynBase
DynBase.h:
#pragma once
#include <map>
#include <string>
class DynBase;
struct ClassInfo;
bool Register(ClassInfo* ci);
typedef DynBase* (*funCreateObject)();
//Assistant class to create object dynamicly
struct ClassInfo
{
public:
string Type;
funCreateObject Fun;
ClassInfo(string type, funCreateObject fun)
{
Type = type;
Fun = fun;
Register(this);
}
};
//The base class of dynamic created class.
//If you want to create a instance of a class ,you must let
//the class derive from the DynBase.
class DynBase
{
public:
static bool Register(ClassInfo* classInfo);
static DynBase* CreateObject(string type);
private:
static std::map<string,ClassInfo*> m_classInfoMap;
};
DynBase.cpp:
#include "stdafx.h"
#include "DynBase.h"
std::map< string,ClassInfo*> DynBase::m_classInfoMap = std::map<string,ClassInfo*>();
bool DynBase::Register(ClassInfo* classInfo)
{
m_classInfoMap[classInfo->Type] = classInfo;
return true;
}
DynBase* DynBase::CreateObject(string type)
{
if ( m_classInfoMap[type] != NULL )
{
return m_classInfoMap[type]->Fun();
}
return NULL;
}
bool Register(ClassInfo* ci)
{
return DynBase::Register(ci);
}
Derived Class
DerivedClass.h:
class DerivedClass : public DynBase
{
public:
virtual ~ DerivedClass ();
DerivedClass ();
static DynBase* CreateObject(){return new DerivedClass ();}
private:
static ClassInfo* m_cInfo;
};
DerivedClass.cpp:
#include "stdafx.h"
#include "DynBase.h"
#include "DerivedClass.h"
DerivedClass::~ DerivedClass ()
{
// ToDo: Add your specialized code here and/or call the base class
}
DerivedClass:: DerivedClass ()
{
}
ClassInfo* DerivedClass::m_cInfo = new ClassInfo(“DerivedClass”,(funCreateObject)( DerivedClass::CreateObject));
How to Use
int _tmain(int argc, _TCHAR* argv[])
{
DerivedClass * instance = (DerivedClass *)DynBase::CreateObject(“DerivedClass”);
//do something
system("pause");
return 0;
}
Postscript
C++虽然没有反射的功能也能在一定的情况下根据类名来动态创建其实例,虽然使用了全局静态函数以及静态成员这样不是很理想的方法——可也只能用这样的方法了。在我们使用工厂模式的时候,可以使用这样的方法来创建某产品的实例了,而不是使用大把的switch-case语句了。
https://www.cnblogs.com/xudong-bupt/p/6643721.html
https://blog.csdn.net/klarclm/article/details/7352091