MFC 动态创建机制 模拟实现
动态创建的难点在于,你不能够根据从文件中或者用户的输入中根据类名称来创建一个对象。
MFC实现动态创建的方法还是在于CRuntimeClass ,及其建立起来的类型网络。它在CRuntimeClass中加入了新的成分:CRuntimeClass::CreateObject 函数,因为CRuntimeClass中已经存储了对于类的名称,所以当获得用户输入的类名称后,就可以在CRuntimeClass中查找,如果名称相同,那么就调用CRuntimeClass::CreateObject函数产生动态对象,从而实现了动态创建。
下面我们来看具体的定义和实现:
struct CRuntimeClass
{
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema;
CObject *(PASCAL *m_pfnCreateObject)();
CRuntimeClass * m_pBaseClass;
//下面的CreateObject和Load函数是新增的
CObject* CreateObject();
static CRuntimeClass * PASCAL Load();
static CRuntimeClass * pFirstClass;
CRuntimeClass * m_pNextClass;
};
我们接下来又故伎重演,用两个宏来定义和实现这些:
它们是 DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE
分别定义如下:
#define DECLARE_DYNCREATE (class_name)/
DECLARE_DYNMIC(clsss_name)/
static CObject * PASCAL CreateObject();
明显就是先定义原先的CRuntimeClass再加上CreateObject的定义,这样就可以知道,拥有动态创建能力的类,肯定有类型识别的能力。
#define IMPELEMENT_DYNCREATE /
CObject * class_name::CreateObject()/
{ return new class_name;}/
_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name::CreateObject);
首先实现CreateObject函数,很简单,用new 创建一个对象就好,呵呵。
然后,就是CRuntimeClass 的赋值,包括将CreateObject赋值给 m_pfnCreateObject成员。
//假设从用户的输入来创建对象,那么Load模拟如下
CRuntimeClass * PASCAL CRuntimeClass::Load()
{
string szClassName;
cout<<"请输入一个类的名称..."<<endl;
cin>>szClassName;
CRuntimeClass * pClass;
for(pClass=pFirstClass;pClass!=NULL; pClass=pClass->pNextClass)
{
if(szClassName==string(pClass->m_lpszClassName))
return pClass;
}
//如果没有找到对应的CRuntimeClass ,那么返回NULL
return NULL;
}
最后,我们就可以这样来模拟动态创建了:
CRuntimeClass * pRunClass=CRuntimeClass::Load();
if(pRunClass)
{
CObject * lpObject=pRunClass->CreateObject();
或者
CObject * lpObject=pRunClass->m_pfnCreateObject();
然后就可以调用 lpObject对象所对应的函数了。
假设,这个类为 CWnd 那么就可以这样:
( CWnd *) lpObject->ShowWindow();
}
至此,动态创建的模拟完成,下一篇继续 MFC的永久保存机制的模拟。