IMPLEMENT_DYNAMIC是实现“运行时类型识别”宏,与之相对应的是DECLARE_DYNAMIC(声明“运行时类型识别”宏)。也就是说 你在.CPP文件中如果看见有IMPLEMENT_DYNAMIC,则在.H文件中必定有DECLARE_DYNAMIC的声明。
DECLARE_DYNAMIC/DEClARE_DYNAMIC是为了确定运行时对象属于哪一个类而定义的宏。
DEClARE_DYNCREATE/IMPLEMENT_DYNCREATE是为了“动态创建"类的实例而定义的宏。new可以用来创建对象,但不是动态的。比如说,你要在程序中实现根据拥护输入的类名来创建类的实例,下面的做法是通不过的:
char szClassName[60];
cin >> szClassName;
CObject* pOb=new szClassName; //通不过
这里就要用到DEClARE_DYNCREATE/IMPLEMENT_DYNCREATE定义的功能了。

定义:
//
// Helper macros for declaring CRuntimeClass compatible classes

#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name) \
protected: \
    static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
    static const CRuntimeClass class##class_name; \
    static CRuntimeClass* PASCAL GetThisClass(); \
    virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \
protected: \
    static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
    static CRuntimeClass class##class_name; \
    static CRuntimeClass* PASCAL GetThisClass(); \
    virtual CRuntimeClass* GetRuntimeClass() const; \

#else
#define DECLARE_DYNAMIC(class_name) \
public: \
    static const CRuntimeClass class##class_name; \
    virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \
public: \
    static CRuntimeClass class##class_name; \
    virtual CRuntimeClass* GetRuntimeClass() const; \

#endif

引用:
DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC

#define DECLARE_DYNAMIC(class_name)\   
public:\
    static CRuntimeClass class##class_name;\
    //声明一个类型为CRuntimeClass的静态public成员变量,变量名是由字符串"class"
    //与所指定的类的类名组成。举例而言,如果你写DECLARE_DYNAMIC(CMyView),则等于声明了一个
    // static CRuntimeClass classCMyView静态变量

virtual CRuntimeClass* GetRuntimeClass() const;\
    //声明一个虚函数,函数名为GetRuntimeClass,返回值为CRuntimeClass类型的指针
    //无参数,并且是个const函数

#define IMPLEMENT_DYNAMIC(class_name,bass_class_name)\
       _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)

#define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)\
    static char _lpsz##class_name[]= #class_name;\
    //定义一个C类型字符串静态变量,变量名由"_lpsz"和指定类的类名组成,变量值为该指定类型的名字
    //比如是CMyView,那么定义的就是static char _lpszCMyView="CMyView";

CRuntimeClass class_name::class##class_name = {\
        _lpsz##class_name,sizeof(class_name),wSchema,pfnNew,\
            RUNTIME_CLASS(base_class_name),NULL};\
    //给之前在DECLARE_DYNAMIC里定义的CRuntimeClass类型的静态成员变量赋值
    //当然,除最后一个m_pNextClass没有赋值(赋值为NULL,它由下面的结构处理)

static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);\
    //初始化一个名为"_init_##class_name"的AFX_CLASSINIT静态结构,主要作用是给指定的class_name的
    //class##class_name静态变量的最后一个成员m_pNextClass赋值,具体见下面解释AFX_CLASSINIT中

CRuntimeClass* class_name::GetRuntimeClass() const\
        { return &class_name::class##class_name;}\
    //之前在DECLARE_DYNAMIC里定义的GetRuntimeClass的实现,很简单,就一个return语句。

#define RUNTIME_CLASS(class_name)\
        (&class_name::class##class_name)
//这部分之所以单独define出一个宏,主要是为了方便从某个指定的class直接得到它的CRuntimeclass静态成员

//以下是解释AFX_CLASSINIT结构,注意,这不是一个宏
//为了看得更加清楚,我按照struct定义的惯常格式来写这个struct的定义
struct AFX_CLASSINIT {
    AFX_CLASSINIT(CRuntimeClass *pNewClass);
};

AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass *pNewClass)
{
    pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;
    //让m_pNextClass指向pFirstClass所指的CRuntimeClass变量

CRuntimeClass::pFirstClass = pNewClass;
    //让pFirstClass指向pNewClass所指的变量,也就是本class的CRuntimeClass静态变量
}

转载于:https://blog.51cto.com/iandcpp/271244

DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC宏相关推荐

  1. MFC比较好的一篇文章

     frameborder="0" style="display: none;"> 登录 | 注册 收藏成功 确定 收藏失败,请重新收藏 确定 查看所有 ...

  2. 最最基本的框架宏使用RUNTIME_CLASS DECLARE_DYNAMIC IMPLEMENT_RUNTIMECLASS

    Demo.h // 简化封装 // 部分的内容在MFC中都是固化的,所以理解并加以记忆是必要的 // #pragma once #include <windows.h>/// // 调试支 ...

  3. VC/MFC中常用宏的含义

    VC/MFC中常用宏的含义 Visual C++ MFC 中常用宏的含义(转载)     AND_CATCHAND_CATCH AND_CATCH(exception_class,exception ...

  4. VC宏定义 及常用宏定义说明

    1. 宏定义的格式 宏定义的一般格式是: #define  标识符  字符串 其中,标识符和字符串之间用空格隔开.标识符又称宏名,为了区别于一般变量,通常用英文大写字母表示:字符串又称宏体,可以是常 ...

  5. 深入浅出mfc学习笔记——六大关键技术之仿真_运行时和动态创建

    1:PS88:MFC的类层次结构 <1>CObject <2>CCmdTarget,CDocument <3>CCmdTarget_CWinThread_CWinA ...

  6. MFC类结构-1、CObject类

    CObject是"MFC类之母",由它派生出庞大的类体系.CObject并不是对整个类体系进行语义抽象的结果,它只为所有派生类定义几种功能特性.由于这几项功能应用于MFC的大部分类 ...

  7. MFC六大核心机制之四:永久保存(串行化)

    永久保存(串行化)是MFC的重要内容,可以用一句简明直白的话来形容其重要性:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿.那怕我们的记事本.画图等小程 ...

  8. MFC中的动态创建与运行时识别

    MFC中支持运行时类型识别与动态创建.这更多的是设计问题.理解了其中的设计,可以更快定位用MFC框架开发的代码.通过研究MFC实现这些的细节,可以更快地掌握其他开发框架的设计思想. 宏定义中的&quo ...

  9. RUNTIME_CLASS

    RUNTIME_CLASS RUNTIME_CLASS( class_name ) [参数] class_name:类的实际名字(不用引号括起来). [说明] 利用这个宏通过C++类的名字获得一个运行 ...

最新文章

  1. Android开发之android studio快捷键大全
  2. 部署也是工程的一部分,也要编程(自动化)
  3. 解决Maven工程中报 Missing artifact jdk.tools:jdk.tools:
  4. Unity3D:Graphics.BlitMultiTap方法
  5. Linux学习笔记---修改CPU频率为自动调节模式
  6. Java中,异常处理try catch的作用域是局部的
  7. 求解偏微分方程开源有限元软件deal.II学习--Step 11
  8. 视觉SLAM之词袋(bag of words) 模型与K-means聚类算法浅析
  9. 北理乐学C语言寻找特殊偶数,北理乐学C语言答案-最新教程.doc
  10. Javashop连锁门店管理系统带您玩转获客
  11. 小米便签类间关系图绘制方法
  12. 论文笔记二 Positive, Negative and Neutral: Modeling Implicit Feedback inSession-based News Recommendatio。
  13. android 权限开启回调,Android M请求onSurfaceTextureAvailable回调权限不在活动
  14. 2012蓝桥杯C++本科 取球游戏
  15. dataframe一列拆分成多列
  16. throw new Error() 真实的用法和throw error 的方法
  17. 简易版 图书管理系统
  18. 用Python脚本能获取Wifi密码么?能。
  19. matlab ccd采集,CCD数据采集.doc
  20. python抓取微博热搜列表

热门文章

  1. JAVA中的集合与排序
  2. 分布式服务框架 Zookeeper(二)官方介绍
  3. 加速企业数字化转型,首届Spring Summit技术峰会圆满落幕
  4. python formatters 与字符串 小结 (python 2)
  5. 2013年中国高校网购实力排行榜
  6. android 解决ListView点击与滑动事件冲突
  7. 在Linux下进行Apache+tomcat整合
  8. 性能测试之计数器的阀值(windows)
  9. “比特币耶稣”罗杰·沃推特赠币,留下BCH钱包地址就有份
  10. Coinbase宣布在以太坊经典上市前进行最终测试