您的位置:首页 > 编程语言 > C语言/C++

MFC六大关键技术之仿真学习笔记(五)

2015-06-06 20:37 691 查看
            前面所有的基础,你可以说你觉得云里雾里的,所谓的"类别型录"网到底可以干什么,我们为什么需要花费这么多功夫去构建呢,在这一节我会慢慢道来。

我们希望在程序运行过程中动态生成某种"类别型录"中的对象,如 CWnd 我们可能会有这样的思路:

CObject *pClass = CRuntimeClass::CreateObject("CWnd"); 

或者 

CRuntimeClass *pRtclass = CRuntimeClass::Load("CWnd"); 

CObject *pClass = pRtclass -> CreateObject();

确实,如你所想,MFC也为你完成了类似这样的一套工作,这就是动态创建。

*DYNAMIC CREATION(动态创建)

首先我们对CRuntimeClass进行修改:

struct CRuntimeClass
{
//Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema;
CObject *(PASCAL *m_pfnCreateObject)();
CRuntimeClass *m_pBaseClass;

CObject* CreateObject();
static CRuntimeClass* PASCAL Load();

static CRuntimeClass* pFirstClass;
CRuntimeClass* m_pNextClass;
};
我们看到增加了两个成员函数:

CObject* CreateObject();
static CRuntimeClass* PASCAL Load();
当然,在C++的struct中允许增加成员函数,而在C语言中我们只能够运用函数指针实现成员函数。

我们来看看CObject* CreateObject() 的实现:

CObject* CRuntimeClass::CreateObject()
{
if (m_pfnCreateObject == NULL)
{
TRACE1("error:Trying to create object which is not DECLARE_DYNCREATE OR DECLEARE_SERIAL: %hs.\n", m_lpszClassName);
return NULL;
}

CObject* pObject = NULL;
pObject = (*m_pfnCreateObject)();

return pObject;
}
即:CObject* CreateObject() 会在调用CRuntimeClass的m_pfnCreateObject指向的函数(若不为NULL)

再看看static CRuntimeClass* PASCAL Load()的实现:

CRuntimeClass* PASCAL CRuntimeClass::Load()
{
char szClassName[64];
CRuntimeClass* pClass;

std::cout << "enter a class name...\n";
std::cin >> szClassName;

for (pClass = pFirstClass; pClass != NULL;pClass=pClass->m_pNextClass)
{
if (strcmp(szClassName,pClass->m_lpszClassName) == 0)
{
return pClass;
}
}
TRACE1("error: Class Not Found: %s\n", szClassName);
return NULL;
}
即:Load()函数完成对"类别型录"进行遍历,返回符合的CRuntimeClass指针,从而进行我们下一步的动态创建。

其次,在动态创建时MFC加入了两个新的宏:

#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \
static CObject* PASCAL CreateObject();
#define IMPLEMENT_DYNCREATE(class_name,base_class_name) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name ;} \
_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name::CreateObject)
其实DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 增加实现了

static CObject* PASCAL CreateObject();
CObject* PASCAL class_name::CreateObject()
{ return new class_name ;}
即:在类中添加唯一一个静态成员函数,创建返回一个自身产生的对象。

_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name::CreateObject)
即:类中的CRuntimeClass对象的m_pfnCreateObject 被指向 类的静态成员函数:CreateObject() ;(如 : CWnd::CreateObject ),并非CRuntimeClass中的 CObject*
CRuntimeClass::CreateObject();


动态创建CFrameWnd如下图:



当然在运用时我们只需要在声明中加入DECLARE_DYNCREATE(class_name),cpp文件中加入IMPLEMENT_DYNCREATE(class_name,base_class_name) 即可完成以上复杂的过程。

当"类别型录"网中m_pfnCreateObject不为NUL的,都可以执行动态创建。

此处我们在main函数中测试一下仿真:

int _tmain(int argc, _TCHAR* argv[])
{
CWinApp *pApp = AfxGetApp();
pApp->InitApplication();
pApp->InitInstance();
pApp->Run();

CRuntimeClass* pClassRef;
CObject* pOb;
while (true)
{
if ((pClassRef = CRuntimeClass::Load()) == NULL)
{
break;
}
pOb = pClassRef->CreateObject();
if (pOb != NULL)
{
pOb->SayHello();
}
}
system("pause");
return 0;
}
测试结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  MFC c++