C++根據類名動態創建對象


參考的文章:

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 }

直接根據類名稱調用接口即可得到對象。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM