MFC运行时类信息
用途:
程序在运行时,获取对象类的信息及类的继承关系
实现:
1、定义的类必须继承自CObject类。 2、类内声明宏DECLARE_DYNAMIC(),类外实现宏IMPLEMENT_DYNAMIC() 3、使用:
BOOL CObject::IsKindOf(CRuntimeClass* pClass)//对象是否属于某个类
CRuntimeClass* GetRuntimeClass( );//获取对象运行时类信息,经常使用RUNTIME_CLASS(类名)代替。
示例:
class CAnimal:public CObject
{
DECLARE_DYNAMIC(CAnimal)
};
IMPLEMENT_DYNAMIC(CAnimal,CObject)
class CDog:public CAnimal
{
DECLARE_DYNAMIC(CDog)
};
IMPLEMENT_DYNAMIC(CDog,CAnimal)
int main(int argc, char* argv[])
{
printf("Hello World!\n");
CDog dog;
if(dog.IsKindOf(RUNTIME_CLASS(CAnimal)))
{
printf("dog is an animal\n");
}
CAnimal animal;
CRuntimeClass* rt=animal.GetRuntimeClass();
printf("运行时类信息,类名:%s,大小:%d,版本:%d\n",rt->m_lpszClassName,rt->m_nObjectSize,rt->m_wSchema);
if(animal.IsKindOf(rt))
{
printf("animal is an animal\n");
}
return 0;
}
动态创建对象
作用和意义:
一般编程时,使用系统的类定义对象,调用对象的成员函数完成相关的功能。有了动态创建,由用户定义类,系统函数创建该类的对象,由底层代码创建上层类的对象。
实现:
1、定义类必须继承自CObject类。 2、类内声明宏DECLARE_DYNCREATE,类外实现宏IMPLEMENT_DYNCREATE 3、使用:
实例:
class CAnimal:public CObject
{
DECLARE_DYNCREATE(CAnimal)
};
IMPLEMENT_DYNCREATE(CAnimal,CObject)
class CDog:public CAnimal
{
DECLARE_DYNCREATE(CDog)
};
IMPLEMENT_DYNCREATE(CDog,CAnimal)
//定义动态创建对象的函数
void CreateInstance(CRuntimeClass* pClass)
{
CObject *pObj=pClass->CreateObject();
printf("对象地址:%p\n",pObj);
printf("类名:%s\n",pClass->m_lpszClassName);
delete pObj;
}
int main(int argc, char* argv[])
{
printf("Hello World!\n");
CreateInstance(RUNTIME_CLASS(CDog));
return 0;
}
具体实现细节
类继承体系中每个类都定义一个CRuntimeClass类型的静态数据成员,并定义静态成员函数 _GetBaseClass、GetThisClass及虚函数GetRuntimeClass。
struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif
// Operations
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;
// dynamic name lookup and creation
static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);//搜AfxGetModuleState()->m_classList,如果不成功再search classes in shared DLLs, 即pModuleState->m_libraryList->m_classList
static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCSTR lpszClassName);//从类名字符串,用FromName返回对应的CRuntimeClass,然后调用CRuntimeClass的成员函数CreateObject()
static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);
// Implementation
void Store(CArchive& ar) const;
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);//从CArchive读入类名字符串,然后返回对应的CRuntimeClass的对象。
// CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass; // linked list of registered classes
const AFX_CLASSINIT* m_pClassInit;
};