上回提要:在我们实现了我们的类型识别,不过在这里,光输出还不够,我们还需要一个类型比较的方法:实现起来也是极其简单的
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
{
CRuntimeClass* pClassThis = GetRuntimeClass();
while (pClassThis != NULL)
{
if (pClassThis == pClass)
return TRUE;
pClassThis = pClassThis->m_pBaseClass;
}
return FALSE;
}
直接通过该方法获取对应类中的类型识别单元,然后递归向下的比较,以此来判断是否为某一类型~~~,简直不要更加简单
在我们拥有了对于一个类型的识别的功能之后,现在就该考虑另一个问题了:如何在程序执行期间根据动态获得一个类的名称来动态创建一个对应的类的对象,其实学习了这么长时间的设计模式之后,我曾经想过直接通过模板和工厂模式也都是可以很简单那实现的,不过这个都已经不是重点了,这里我们就来看看MFC中的动态创建的实现:
其实废话了那么久。MFC中的实现方式也是很简单,就是在类型识别单元中加入了提供对应对象构造函数的方法,(其实其他的那几种写法说到底不也是这么玩的么?)
具体的操作如下:
struct CRuntimeClass
{
//属性
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema;
CObject* (PASCAL* m_pfnCreateObject)(); //NULL => abstract class
CRuntimeClass* m_pBaseClass;
CObject* CreateObject();
static CRuntimeClass* PASCAL Load();</span>
//运行时类型的对象会被链接到一条链表上
static CRuntimeClass* pFirstClass; //型录的起点
CRuntimeClass* m_pNextClass; //被链接到一条型录上
};
添加了中间部分的2个成员,其作用分别为一个是型录提供动态创建的方法,另一个则是判断是否具有动态创建能力的方法,在这里顺便补充一句,之前一直不明所以的函数指针m_pfnCreateObject在这里也展示了他的作用,用来传递动态创建的方法
他们的实现部分如下:
//CreateObject()
CObject* CRuntimeClass::CreateObject()
{
if (m_pfnCreateObject == NULL)
{
TRACEL("Error: Trying to create object which is not "
"DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n", m_lpszClassName);
return NULL;
}
CObject* pObject = NULL;
pObject = (*m_pfnCreateObject)();
return pObject;
}
//Load()
CRuntimeClass* PASCAL CRuntimeClass::Load()
{
char szClassName[64];
CRuntimeClass* pClass;
cout << "enter a class name...";
cin >> szClassName;
for (pClass = pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)
{
if (strcmp(szClassName, pClass->m_lpszClassName) == 0)
return pClass;
}
T