C++是一款功能強大的基於C語言的計算機編程語言。它不但能支持各種C語言的功能,還可以對包括面向對象在內的各種程序設計風格的支持。我們今天會為大家詳細介紹一下有關C++動態創建對象的一些應用技巧。
Native C++是不支持根據類名的C++動態創建對象,比如從一個文本文件中讀取類名然後構造一個對象.主要原因是沒有豐富的動態元信息,沒有單根類庫。然而可以用幾種技術進行實現。如果是類似Spring那樣的根據配置文件運行時產生實現某個接口的對象,那麼在Windows中至少有三種辦法:
1. LoadLibrary + GetProcAdress。這個不用多解釋,可以把DLL和Proc的名字動態傳入。
2. COM,根據動態獲得的CLSID調用GetClassObject獲得IClassFactory接口,然後CreateInstance。或者直接調用CoCreateInstance/CoCreateInstanceEx動態產生CoClass。
3. MFC dynamic creation。
Native C++不能在運行時編譯代碼並即時產生對象,所以JIT的動態生成在C++裡做不到。在MFC中,可以參考,總結如下:
MFC的C++動態創建對象可能是最容易使用的方案。查了一下MFC中RTCI的實現,總結一下:
DECLARE_ DYNCREATE(class_name)宏展開後是如下形式:
假設class_name是“CMyClass”
- public:
- static CRuntimeClass classCMyClass;
- virtual CRuntimeClass* GetRuntimeClass() const;
- static CObject* CreateObject();
這幾行會被加入到CMyClass類的聲明中。
IMPAEMENT_DYNCREATE(classname,base_classname)宏定義比較復雜,這個宏展開後類似如下的樣子:
- AFX_DATADEF CRuntimeClass CMyClass::classCMyClass = {
- "CMyClass",sizeof(CMyClass),0xFFFF,NULL,RUNTIME_CLASS(CObject),NULL};
- static const AFX_CLASSSINIT _init_CMyClass(&CMyClass::classCMyClass);
- CRuntimeClass* CMyClass::GetRuntimeClass() const
- {
- Return & CMyClass::classCMyClass;
- }
- CObject* PASCAL CMyClass::CreateObject()
- {
- return new CMyClass;
- }
這個宏做了如下3件事情:
1.初始化CRuntimeClass類型的成員變量classCMyClass
2.創建靜態AFX_CLASSINIT結構,該結構如下:
- Struct AFX_CLASSINIT
- {AFX_CLASSINIT(CRuntimeClass* pNewClass);};
這個步驟地主要作用是把CMyClass::classCMyClass添加到MFC的一個內部鏈表中去。
3.覆蓋GetRuntimeClass(),以返回成員變量classCMyClass的地址。
- RUNTIME_CLASS宏展開後如下:
- (&class_name::class##class_name)
C++動態創建對象的時候,調用CRuntime::CreateObject()方法。
這個方法實際上會去調用CRuntime中的一個成員指針,這個指針指向的正是CMyClass::CreateObject()方法。
由上可見,RuntimeClass宏可接受字符串作為參數,但是,仍然需要在編譯時定義好需要動態創建的對象類型,上文例子中為CMyClass。通過MFC的這個特性,理論上還是可以從配置文件中讀取文本,然後按照文本指定的類型C++動態創建對象,但必須要求在編譯時就存在這種類型,不能像動態語言那樣無限制的擴展。另外CMyClass必須繼承自CObject。