如果把对象保存在文件上,读取的时候就会面临一个问题,如何解析文件中的数据?怎样才能把文件中的数据和具体的型别对应起来?这就是动态创建问题。
最直接的想法是给每个类一个编号。假如有三个类,CDuckClass, CCockClass, CMonkeyClass
他们都派生自CRootClass,下面是一种可行的方案。
void LoadFile(char* pszFileName) { ifstream infile(pszFileName); int iType; infile >> iType; CRootClass* pRootClass = NULL; switch (iType) { case 0: pRootClass = new CDuckClass; break;; case 1: pRootClass = new CCockClass; break; case 2: pRootClass = new CMonkeyClass; break; default: break; } if (NULL != pRootClass) { pRootClass->Display(); } }
但这样做LoadFile必须知道已有的三个类,对它们也就产生了依赖。如果新增一个CFoxClass,就需要新的编号,同时要修改LoadFile代码。
如果把创建工作转移到具体的类里面来完成,同时在保存对象时候将类名称写入文件,然后再写入对象数据,那么LoadFile就可以不必知道需要创建一个什么样的类,之要读一个类名,然后调用它的创建函数创建对象就可以了。因此有了下面的做法
#include <iostream> using namespace std; class CRootClass { public: virtual void Display() = 0; }; typedef CRootClass* (*CREATECLASSOBJECT)(); class CClassType { public: CClassType(char* szClassName, CREATECLASSOBJECT pfnCreate) { m_pClassName = szClassName; m_pfnCreateClassObject = pfnCreate; m_pNext = CClassType::m_pTheFirst; CClassType::m_pTheFirst = this; } public: static CClassType* m_pTheFirst; CREATECLASSOBJECT m_pfnCreateClassObject; char* m_pClassName; CClassType* m_pNext; }; class CDuckClass : public CRootClass { public: static CClassType classType; public: static CRootClass* CreateClassObjecet() { return new CDuckClass; } public: virtual void Display() { cout << "this is a CDuckClass Object" << endl; } }; class CCockClass : public CRootClass { public: static CClassType classType; public: static CRootClass* CreateClassObjecet() { return new CCockClass; } public: virtual void Display() { cout << "this is a CCockClass Object" << endl; } }; class CMonkeyClass : public CRootClass { public: static CClassType classType; public: static CRootClass* CreateClassObjecet() { return new CMonkeyClass; } public: virtual void Display() { cout << "this is a CMonkeyClass Object" << endl; } };
使用方式:
int main() { CClassType* pclassType = CClassType::m_pTheFirst; while (pclassType != NULL) { if (strcmp(pclassType->m_pClassName, "CDuckClass") == 0) { break; } pclassType = pclassType->m_pNext; } CRootClass* pRootClass = NULL; if (pclassType != NULL) { pRootClass = pclassType->m_pfnCreateClassObject(); pRootClass->Display(); } delete pRootClass; return 0; }
这样就做到了动态创建。在实际产品开发中,如果有一个系列的产品需要动态创建,就可以用一个static对象把他们串
在一起,只需要持有CClassType::m_pTheFirst就可以进行查找创建了