// DynBase.h #ifndef __DYNBASE_H__ #define __DYNBASE_H__ #include <string> class Object; class ClassInfo; typedef Object* (*ObjectConstructorFn)(void); bool Register(ClassInfo* ci); using namespace std; class ClassInfo { public: ClassInfo(const std::string className,ObjectConstructorFn ctor) :m_className(className) ,m_objectConstructor(ctor) { Register(this); } virtual ~ClassInfo(){} Object* CreateObject()const { return m_objectConstructor ? (*m_objectConstructor)() : 0; } bool IsDynamic()const { return NULL != m_objectConstructor;} const std::string GetClassName()const { return m_className;} ObjectConstructorFn GetConstructor()const{ return m_objectConstructor;} public: string m_className; ObjectConstructorFn m_objectConstructor; }; #define DECLARE_CLASS(name) protected: static ClassInfo ms_classinfo; public: virtual ClassInfo* GetClassInfo() const; static Object* CreateObject(); #define IMPLEMENT_CLASS_COMMON(name,func) ClassInfo name::ms_classinfo((#name), (ObjectConstructorFn) func); ClassInfo *name::GetClassInfo() const {return &name::ms_classinfo;} #define IMPLEMENT_CLASS(name) IMPLEMENT_CLASS_COMMON(name,name::CreateObject) Object* name::CreateObject() { return new name;} class Object { DECLARE_CLASS(Object) public: Object(){} virtual ~Object(){} static bool Register(ClassInfo* ci); static Object* CreateObject(string name); }; #endif
//DynBase.cpp #include "StdAfx.h" #include <map> #include "DynBase.h" static std::map< string,ClassInfo*> *classInfoMap = NULL; using namespace std; IMPLEMENT_CLASS(Object) bool Object::Register(ClassInfo* ci) { if(!classInfoMap) { classInfoMap = new std::map< string,ClassInfo*>(); } if(ci) { if(classInfoMap->find(ci->m_className) == classInfoMap->end()){ classInfoMap->insert(std::map< string,ClassInfo*>::value_type(ci->m_className,ci)); } } return true; } Object* Object::CreateObject(std::string name) { std::map< string,ClassInfo*>::const_iterator iter = classInfoMap->find(name); if(classInfoMap->end() != iter) { return iter->second->CreateObject(); } return NULL; } bool Register(ClassInfo* ci) { return Object::Register(ci); }
//test.cpp #include<iostream> #include<cstring> #include "DynBase.h" using namespace std; class A : public Object { DECLARE_CLASS(A) public : A(){cout<<hex<<(long)this<<" A constructor!"<<endl;} ~A(){cout<<hex<<(long)this<<" A destructor!"<<endl;} }; IMPLEMENT_CLASS(A) class B : public Object { DECLARE_CLASS(B) public : B(){cout<<hex<<(long)this<<" B constructor!"<<endl;} ~B(){cout<<hex<<(long)this<<" B destructor!"<<endl;} }; IMPLEMENT_CLASS(B) int main() { Object* p = Object::CreateObject("A"); delete p; system("pause"); return 0; }
转自: http://www.oschina.net/code/snippet_230828_9913