參考的文章:
http://blog.csdn.net/jnu_simba/article/details/9318799
http://blog.csdn.net/xiaoxiaoyusheng2012/article/details/45438899
按照網上大部分人的思路,將類名和創建的函數保存成一個map,然后創建對象時根據類型匹配創建函數即可,我自己整理的代碼如下:
1、object.h
1 #ifndef OBJECT_H 2 #define OBJECT_H 3 4 #include <string> 5 #include <map> 6 7 typedef void* (*Constructor)(); 8 9 class CObjectFactory 10 { 11 public: 12 static void registerClass(std::string className, Constructor constructor) 13 { 14 constructors()[className] = constructor; 15 } 16 17 static void* createObject(const std::string& className) 18 { 19 Constructor constructor = NULL; 20 21 if(constructors().find(className) != constructors().end()) 22 constructor = constructors().find(className)->second; 23 24 if ( constructor == NULL ) 25 return NULL; 26 27 return (*constructor)(); 28 } 29 30 private: 31 inline static std::map<std::string, Constructor>& constructors() 32 { 33 static std::map<std::string, Constructor> instance; 34 return instance; 35 } 36 }; 37 38 39 #define REGISTER_CLASS(class_name) \ 40 class class_name##Helper { \ 41 public: \ 42 class_name##Helper() \ 43 { \ 44 CObjectFactory::registerClass(#class_name, class_name##Helper::creatObjFunc); \ 45 } \ 46 static void* creatObjFunc() \ 47 { \ 48 return new class_name; \ 49 } \ 50 }; \ 51 class_name##Helper class_name##helper; 52 53 54 #endif
主要的設計思路都在這里體現了:
a、設計一個工廠類,用於動態創建對象,根據前面的思路,需要實現兩個接口,即注冊類名稱和創建函數的接口、動態創建的接口,且都申明為static;
b、沒有直接使用類的static變量保存map變量,而是使用了一個static函數,函數內部申明一個static變量map,這樣的好處是整個代碼都可以在頭文件里實現,不需要額外的cpp文件。因為如果采用類的static變量,需要再建一個cpp文件初始化這個變量;
c、REGISTER_CLASS宏用於注冊,它創建了一個輔助類和一個對應的輔助類對象
2、test.h
1 #ifndef TEST_H 2 #define TEST_H 3 4 5 #include <iostream> 6 7 class CClassTest 8 { 9 public: 10 CClassTest() 11 { 12 std::cout<<"CClassTest\n"; 13 } 14 }; 15 16 class CClassTest2 17 { 18 public: 19 CClassTest2() 20 { 21 std::cout<<"CClassTest2\n"; 22 } 23 }; 24 25 26 27 28 #endif
主要用於測試,比較簡單
3、test.cpp
1 #include "test.h" 2 #include "object.h" 3 4 REGISTER_CLASS(CClassTest) 5 REGISTER_CLASS(CClassTest2)
注冊類的宏應放到cpp文件中,如果放到頭文件中會報錯。
4、main.cpp
1 #include "object.h" 2 #include "test.h" 3 #include <iostream> 4 5 int main() 6 { 7 CClassTest* test = static_cast<CClassTest*>(CObjectFactory::createObject("CClassTest")); 8 CClassTest2* test2 = static_cast<CClassTest2*>(CObjectFactory::createObject("CClassTest2")); 9 10 delete test; 11 delete test2; 12 13 return 0; 14 }
直接根據類名稱調用接口即可得到對象。
