【C++】【MFC】运行时类信息机制和动态创建机制
MFC运行时类信息机制常用于获取当前类是否属于目标类的子类,使用IsKindOf()函数
创建条件:
1、必须继承于CObject类;
2、
运行时:
类内必须声名宏DECLARE_DYNAMIC(class_name);
类外必须实现宏IMPLENMENT_DYNAMIC(class_name, base_class_name);
动态创建:
类内必须声名宏DECLARE_DYNCREATE(class_name);
类外必须实现宏IMPLENMENT_DYNCREATE(class_name, base_class_name);
Code:
1 #include <afxwin.h> 2 #include <iostream> 3 4 5 class CAnimal : public CObject{ 6 DECLARE_DYNAMIC(CAnimal) 7 }; 8 IMPLEMENT_DYNAMIC(CAnimal, CObject) 9 10 11 class CDog : public CAnimal { 12 DECLARE_DYNAMIC(CDog) 13 }; 14 IMPLEMENT_DYNAMIC(CDog, CAnimal) 15 16 17 int main() { 18 CDog yd; 19 std::cout << yd.IsKindOf(RUNTIME_CLASS(CObject)); 20 auto *p = yd.GetRuntimeClass(); 21 std::cout << p->m_pBaseClass->m_lpszClassName; 22 return 0; 23 }
DECLARE_DYNAMIC(class_name)宏替换的代码:
static const CRuntimeClass class##class_name;
virtual CRuntimeClass* GetRuntimeClass() const;
上述定义了一个静态变量和一个虚函数,其中CRuntimeClass类型为一个结构体:
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
CRuntimeClass* m_pBaseClass;
第一个为本类名
第二个为本类大小
第三个为本类版本
第四个当为运行时类信息则为NULL,为动态创建时则是CDog类的地址
第五个为父类地址(CObject类的父类地址为NULL)
至此借助上述代码剖析,每有一个类直接或者间接的继承于CObject,那么都会创建这么一个结构体又因CRuntimeClass的第五个成员为指针并指向父类,所以将形成一个单向链表,而IsKindOf( )就是通过遍历链表将本类和目标类进行比对从而实现。