运行时识别,CObject类的又一个重要特性.
在前面关于CObject的介绍中,我们知道AFX_CLASSINIT这一方法对于运行时识别起到了至关重要的作用.代码如下(出自objcore.cpp):
struct AFX_CLASSINIT
{ AFX_CLASSINIT(CRuntimeClass* pNewClass) { AfxClassInit(pNewClass); } };
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}
经过IMPLEMENT_DYNAMIC的替换后,如:
AFX_DATADEF CRuntimeClass CCmdTarget::classCCmdTarget={
"CCmdTarget",sizeof(CCmdTarget),0xFFFF,NULL,RUNTIME_CLASS(CObject),NULL};
在这里可以大概理解为在MFC中存在着一个以CObject为根节点的CRuntimeClass链表,CObject->m_pNextClass为CCmdTarget
另外从IsKindOf这一函数的源代码也可以看到这一链表的存在及作用
BOOL CObject::IsKindOf(const CRuntimeClass *pClass) const
{
CRuntimeClass *pClassThis=GetRuntimeClass();
while(pClassThis != NULL)
{//如果当前类型不匹配,则继续搜索该类型的父类
if(pClassThis==pClass)
return TRUE;
pClassThis = pClassThis->m_pBaseClass;
}
return FALSE;
}