2019独角兽企业重金招聘Python工程师标准>>>

MFC框架早在标准C++之间提出并实现了类的运行时识别(RTTI)功能,下面记录下基于我对其的理解。

要实现RTTI必须在定义的时候记录下来类的基本信息。MFC构建了一个CRuntimeClass的结构体用以保存类的基本信息。CRun提么Class的定义如下:

struct CRuntimeClass
{LPCSTR m_pszClassName; //类名称int m_nObjectSize; //类的大小UINT m_wSchema; CObject (PASCAL * m_pfnCreateObject)();   CRuntimeClass *m_pBaseClass; //类的基类(父类)static CRuntimeClass *pFirstClass;//保存类信息的链表头指针CRuntimeClass *m_pNextClass;//链表的下一个
};

在定义好这样一个结构体后,在每个类中添加一个这样的成员(静态的)即可。这样的每个实例都可以通过该属性访问到类的相关信息。这样的定义是属于类的所有对象共有的,在定义类的时候就已经定义好了,所以只需要将该属性定义为静态的即可。通过这种做法每个类都保存的类的所有相关信息,但是如果要查找类的相关信息是不够的,所以通过链表的方式将这些类的CRuntimeClass静态属性组织起来,这样可以遍历程序中的所有类,也可以方便查找了。

其具体实现方式为,在MFC框架中定义个DECLARE_DYNAMIC(class_name)的宏,使用宏来实现自动添加该成员(属性)。该宏的具体定义为:

#define DECLARE_DYNAMIC(class_name) \  //class_name为类的名称public: \static CRuntimeClass class##class_name;\  //定义类中的静态成员 ,将该成员的名称固定为class+类名称的形式virtual CRuntimeClass *GetRuntimeClass() const;//定义一个类的返回类相关信息的函数,该函数返回一个CRuntimeClass的指针,该指针指向类的静态成员变量(及前面定义的CRuntimeClass class##class_name)

上面的步骤定义了类中的CRuntimeClass,但是并未提供相应的实现。所以MFC框架继续定义了一个IMPLEMENT_DYNAMIC(class_name,base_class_name)的宏用以实现。其具体定义为:

struct AFX_CLASSINIT
{AFX_CLASSINIT(CRuntimeClass *pNewClass);
}; //定义该结构体主要是为了下面的宏定义中修改保存类信息链表的相关信息,将当前类的静态成员CRuntimeClass添加到链表头。#define RUNTIME_CLASS(class_name) \(&class_name::class##class_name)\\用于下面的宏中返回类中静态成员CRuntimeClass的地址。
#define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew) \static char _lpsz##class_name[]=#class_name;\  //定义一个文件域的变量用以保存类的名称(字符串常量)CRuntimeClass class_name::class##class_name={\_lpsz##class_name,sizeof(class_name),wSchema,pfnNew,RUNTIME_CLASS(base_class_name),NULL};\  \\定义类中的静态成员CRuntimeClass class##class_name,这里面包括类的名称,类的大小,父类等。这里需要注意的是这里的定义并没有改变该结构体中的静态成员变量——指向保存类信息的链表头。static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);\  //定义另一个结构体通过使用该结构的构造方法来实现将链表的头指针指向当前类的CRuntimeClass,将下一个指针指向链表中以前的头,这样就将所有类中的CRuntimeClass信息通过链表连接起来。CRuntimeClass *class_name::GetRuntimeClass() const \{return &class_name::class##class_name;}\ \\定义类中的获取成员变量CRuntimeClass的具体实现。#define IMPLEMENT_DYNAMIC(class_name,base_class_name) \_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0XFFFF,NULL)

上面的这些就是MFC种的RTTI的仿真。需要注意的是,CRuntimeClass的链表中,利用了在链表头插入的方式(对于单链表而言,这应该比较快捷的方法),所以最后添加的类的相关信息在链表的标头位置。另外还需要注意的,这里链表的头在初始化的时候并没有初始化,所以对于所有类的父类及CObject类而言,不能通过简单的DELCARE_DYNAMIC、IMPLEMENT_DYNAMIC宏来实现。

转载于:https://my.oschina.net/eatapple/blog/101907

MFC之RTTI分析(基于侯俊杰的《深入浅出MFC》)相关推荐

  1. 玩转MFC文档视图架构编程1——深入浅出MFC文档/视图架构之基本概念深入浅出MFC文档/视图架构之文档

    原创地址: 深入浅出MFC文档/视图架构之基本概念 http://iis.xrtvu.com/Tech/ShowArticle.asp?ArticleID=276 深入浅出MFC文档/视图架构之文档模 ...

  2. 读侯俊杰的《深入浅出MFC》小记

    1.程序必须在产生窗口之前先利用API函数RegisterClass设定属性(我们称此操作为注册窗口类) 2.消息循环中的TranslateMessage是为了将键盘消息转化,DispatchMess ...

  3. 基于Socket、OpenCV和MFC实现的网络实时视频监控

    文章目录 1 摘要 2 概述 3 客户端的设计与实现 3.1 OpenCV图像处理 3.1.1 cv::VideoCapture类 3.1.2 图像压缩编码 3.2 Socket 网络通信 4 服务器 ...

  4. 在 console mode 中使用 C/C++ 编译器 (作者:侯俊杰)

    在 console mode 中使用 C/C++ 编译器 侯捷 1999.04.08 侯捷 1999.04.08 我总是鼓励 C/C++ 的学习者,在刚接触这个程式语言的时候,先以 console m ...

  5. 红橙Darren视频笔记 ViewGroup事件分发分析 基于API27

    本节目标,通过案例,先看程序运行结果,然后跟踪源码,理解为什么会有这样的输出,继而理解view group的分发机制,感觉和证明题很像呢. 考虑以下程序的运行结果: case1: public cla ...

  6. 商品评论情感分析——基于商品评论建立的产品综合评价模型(1)

    商品评论情感分析--基于用户评论建立的产品综合评价模型(1) 1.背景 1.1问题分析 2.数据预处理 2.1删除无关数据 2.2文本去重 3.情感分析 4.LDA主题模型 4.1评论文本分词 4.2 ...

  7. 《对冲基金建模与分析基于MATLAB》简介及PDF下载

    转 <对冲基金建模与分析--基于MATLAB>简介及PDF下载 内容简介 本书是关于用MATLAB对对冲基金进行建模和分析的入门读物.在对对冲基金的基本概念.分类.相关工具和指标系统介绍的 ...

  8. AsyncHttpClient源码分析-基于Netty的连接池实现

    原文地址:asynchttpclient源码分析-基于Netty的连接池实现 最近项目重构,有了个机会更多接触一个有别于HttpAsyncClient的异步网络框架AsyncHttpClient,是个 ...

  9. Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法

    Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法 1.spreadOutApp尽量平均分配到每个executor上: 2.非spreadO ...

最新文章

  1. [转载]hadoop集群默认配置和常用配置
  2. 一个简单的PHP模板引擎
  3. VC 系统托盘编程,含有气泡提示
  4. 对象序列化(六):应用实例-WPF对象的XAML序列化
  5. Objective-C 内存管理机制
  6. 【机器学习】今天想跟大家聊聊SVM
  7. 五问唐骏:泡妞真的如你说的那么容易?
  8. 数据结构与算法之树的遍历
  9. .NET软件授权管理解决方案Eziriz .NET IntelliLock
  10. 根据rpt文件打印报表
  11. 如何用GraphPad Prism 进行pearson相关性分析
  12. bootstrap怎么强制不换行_Bootstrap方法的软件实现
  13. C++中cout、cin和endl的用法
  14. 微信小程序二手交易系统ssm框架——计算机毕业设计
  15. cloudera-repos 地址
  16. 力扣的组合总和解法 (Python)
  17. 014基于深度学习的脑电癫痫自动检测系统-2018(300引用)
  18. 数据结构(c语言版 第二版 严蔚敏)第一张绪论笔记
  19. 交通流量预测-混合注意力时空图卷积-ASTGCN
  20. PL2303 Windows8.1驱动

热门文章

  1. STM32使用__attribute__后下载提示No Algorithm found for: xxxH - xxxH
  2. 翻译:通过Java编程创建X.509格式的数字签名证书
  3. Linux访问Windows共享目录的方法——smbclient
  4. Python学习笔记(0):开发环境配置
  5. 中间件 - 学习/实践
  6. 软件项目管理第四次作业
  7. php前端计算合计,​excel合计计算公式
  8. 3款App,让你买菜不用愁,送给贤妻的你
  9. 如何在Java中加密和解密zip文件?
  10. layui 弹出层里面添加表格数据