MFC六大机制之四:运行时类信息机制(RTTI)
2015-07-03 22:14
302 查看
首先得说明究竟什么是运行时类信息: 程序在运行时,得到对象的类信息以及所属类的继承层次关系。RTTI(Run-Time
Type Information,运行时类型信息),下边通过一个例子来说明
1.建一个win32控制台程序。
2.将stdafx.h 添加头文件<afxwin.h>。
3.Project-->Settings菜单项中设置使用MFC库
4.编写代码:
![](http://img.blog.csdn.net/20150703222440088?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
注意:
1 派生自CObject
2 添加动态创建的声明宏和实现宏
DECLARE_DYNCREATE(theClass)
IMPLEMENT_DYNCREATE(theClass,baseClass)
为什么上边的程序可以做判断和输出类信息??? 我们来做个宏代换,结果如下
1. CDog有一个静态变量和一个虚函数:
classCDog-----类型是CRuntimeClass,的静态成员变量,保存本类信息和父类运行时类信息地址。
GetRuntimeClass------虚函数,作用是返回classCDog的地址
2. CRuntimeClass:用户可以使用该结构获取一个对象及其基类的运行时信息。
CDog::GetRuntimeClass()
|->&classCDog
|->类的名称,大小,版本等信息
|->&classCAnimal
|->CAnimal类的名称、大小、版本等信息
|->&classCObject
|->CObject类的名称、大小版本等
|->NULL
3. IsKindOf函数是怎么实现的??? 加断点,f11进入函数内部,写出伪代码如下:
原理:
调用GetRuntimeClass获取&classCDog
调用IsDerivedFrom()函数,在函数中,把&classCDog与参数的&classCWnd比较,如果相等,返回TRUE,表示对象属于该类,如果不相等,获取&classCAnimal,继续循环比较,直到&classCObject的父类的变量地址为空,最后,返回FALSE,表示对象不属于该类。
总结:
其实简单的讲就是同通过GetRuntimeClass函数拿到本类的一个静态变量,该变量中保存这本类的信息,和父类的父类的运行时类信息变量的地址,形成一条类的信息链,通过遍历该链表查找类的信息。
Type Information,运行时类型信息),下边通过一个例子来说明
1.建一个win32控制台程序。
2.将stdafx.h 添加头文件<afxwin.h>。
3.Project-->Settings菜单项中设置使用MFC库
4.编写代码:
// Dynamic.cpp : Defines the entry point for the console application. // #include "stdafx.h" //定义支持运行时类信息的类 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[]) { CDog dog; if (dog.IsKindOf(RUNTIME_CLASS(CAnimal))) { printf("dog is a CAnimal !\n"); }else { printf("no no no !\n"); } CRuntimeClass *pClass=dog.GetRuntimeClass(); printf("类的名称:%s\n",pClass->m_lpszClassName); printf("类的大小:%d\n",pClass->m_nObjectSize); return 0; }
注意:
1 派生自CObject
2 添加动态创建的声明宏和实现宏
DECLARE_DYNCREATE(theClass)
IMPLEMENT_DYNCREATE(theClass,baseClass)
为什么上边的程序可以做判断和输出类信息??? 我们来做个宏代换,结果如下
// Dynamic.cpp : Defines the entry point for the console application. // #include "stdafx.h" //定义支持运行时类信息的类 class CAnimal:public CObject { DECLARE_DYNAMIC(CAnimal) }; IMPLEMENT_DYNAMIC(CAnimal,CObject) class CDog:public CAnimal { //DECLARE_DYNAMIC(CDog) public: static const AFX_DATA CRuntimeClass classCDog; virtual CRuntimeClass* GetRuntimeClass() const; }; //IMPLEMENT_DYNAMIC(CDog,CAnimal) //IMPLEMENT_RUNTIMECLASS(CDog, CAnimal, 0xFFFF, NULL) AFX_COMDAT const AFX_DATADEF CRuntimeClass CDog::classCDog = { "CDog", sizeof(class CDog), 0xFFFF, NULL, RUNTIME_CLASS(CAnimal), NULL }; CRuntimeClass* CDog::GetRuntimeClass() const { //return RUNTIME_CLASS(CDog); return ((CRuntimeClass*)(&CDog::classCDog)); } int main(int argc, char* argv[]) { //判断 CDog dog; if(dog.IsKindOf(RUNTIME_CLASS(CWnd))) { printf("dog is a CWnd!\n"); } else { printf("dog is not a CWnd!\n"); } //2 获取类的信息 CRuntimeClass *pClass=dog.GetRuntimeClass(); printf("类的名称:%s\n",pClass->m_lpszClassName); printf("类的大小:%d\n",pClass->m_nObjectSize); return 0; }分析:
1. CDog有一个静态变量和一个虚函数:
classCDog-----类型是CRuntimeClass,的静态成员变量,保存本类信息和父类运行时类信息地址。
GetRuntimeClass------虚函数,作用是返回classCDog的地址
2. CRuntimeClass:用户可以使用该结构获取一个对象及其基类的运行时信息。
struct CRuntimeClass { LPCSTR m_lpszClassName;//类的名称 int m_nObjectSize;//类的大小 UINT m_wSchema; //类的版本 CObject* (PASCAL* m_pfnCreateObject)(); //NULL CRuntimeClass* m_pBaseClass;//父类的运行时类信息变量的地址 ... }结合我们编写的例子我们很容易看到,现在形成了一个类的信息链表,如下:
CDog::GetRuntimeClass()
|->&classCDog
|->类的名称,大小,版本等信息
|->&classCAnimal
|->CAnimal类的名称、大小、版本等信息
|->&classCObject
|->CObject类的名称、大小版本等
|->NULL
3. IsKindOf函数是怎么实现的??? 加断点,f11进入函数内部,写出伪代码如下:
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const { //classCDog的地址 CRuntimeClass* pClassThis = GetRuntimeClass(); return pClassThis->IsDerivedFrom(pClass); pClassThis->IsDerivedFrom(pClass) { //classCDog的地址 const CRuntimeClass* pClassThis = this; while (pClassThis != NULL) { //比较 if (pClassThis == pBaseClass) return TRUE; //获取父类的变量的地址 pClassThis = pClassThis->m_pBaseClass; } return FALSE; } }
原理:
调用GetRuntimeClass获取&classCDog
调用IsDerivedFrom()函数,在函数中,把&classCDog与参数的&classCWnd比较,如果相等,返回TRUE,表示对象属于该类,如果不相等,获取&classCAnimal,继续循环比较,直到&classCObject的父类的变量地址为空,最后,返回FALSE,表示对象不属于该类。
总结:
其实简单的讲就是同通过GetRuntimeClass函数拿到本类的一个静态变量,该变量中保存这本类的信息,和父类的父类的运行时类信息变量的地址,形成一条类的信息链,通过遍历该链表查找类的信息。
相关文章推荐
- uploadify的碎碎念
- 查看图片的Domo
- linux下关机
- Array.sort()
- winsock编程-入门
- 2015070301 - EffactiveJava笔记 - 第52条 通过接口引用对象(1)
- C++中构造函数初始化列表为什么会比构造函数中赋值要高效
- 计算机网络复习资料
- WebView缓存图片的获取
- LintCode比较字符串
- Android Dalvik虚拟机初识
- ThinkPHP RBAC功能小结
- linux文件系统之文件组织方式
- java学习09--选择结构-switch练习、if和Switch使用比较
- JavaSE笔记之<泛型再理解(简化版)>
- TinyAdmin前端展现框架
- 多线程同步方法
- 嵌入式入门
- 能量英语(一)之激情英语
- div与span区别及用法