DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏的详细解释【转】

《深入浅出MFC》书中DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏的详细解释 最近有些朋友在看《深入浅出MFC》的时候,被第三章的几个宏给卡住了,记得我第一次看此书时,也被这几个宏给卡住。当然真正卡人的其实是第一个,也就是DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC。我做了一个详解,供同样被卡住的朋友做个参考:)说明:这两个宏的主要目的,是在所指定的class(比如CView)的声明和实现里,加上一些静态成员函数和静态成员变量。所以,不要管“/”这个换 阅读详情
DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏的详细解释
最近有些朋友在看《深入浅出MFC》的时候,被第三章的几个宏给卡住了,记得我第一次看此书时,也被这几个宏给卡住。当然真正卡人的其实是第一个,也就是DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC。我做了一个详解,供同样被卡住的朋友做个参考:)

说明:这两个宏的主要目的,是在所指定的class(比如CView)的声明和实现里,加上一些静态成员函数和静态成员变量。所以,不要管“\”这个换行标志,就把里面的每一句话当作是在类里的声明或者是实现。另外,“##”和"#"符号我就不不赘述了。
另外,建议结合《深入浅出MFC》这本书,JJHou写了一些展开宏的实例,结合实例看这个解释可能效果会比较好一点:)

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结构,注意,这不是一个宏,请回本贴就可以看下面内容
本帖隐藏的内容需要回复才可以浏览


[ 本帖最后由 成为高手 于 2008-10-29 08:49 编辑 ]
学mfc学到文档,视图和框架的时候,知道必须在这三个类的派生类的类声明 
里加上DECLARE_DYNCREATE,然后在类声明外合适的地方加上IMPLEMENT_DYNCREA 
TE,然后文档,视图和框架,还有文档模板就可以协调工作了。查看msdn,发现 
类似的宏有这几对: 
DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 
DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 
DECLARE_SERIAL 和 IMPLEMENT_SERIAL 

虽然msdn里介绍了他们的作用,但对于它们为什么会起这样的作用心里却没 
底,于是翻了翻mfc的源代码,喜欢钻牛角尖的人可以和我一起来钻一钻。 

1。 
RUNTIME_CLASS宏的定义是这样的: 
#define RUNTIME_CLASS(class_name) 
((CRuntimeClass*)(&class_name::class##class_name)) 
其中##的意思是把##两边的符号都进行宏扩展(如果它们是宏的话),然后把扩展 
后的内容连接在一起,中间不加空格。例如:RUNTIME_CLASS(CView)将被扩展成 
: 
(CRuntimeClass*)(&CView::classCView) 
但这个classCView是什么意思?原来,classCView是由DECLARE_DYNAMIC(CView) 
引入的一个public属性的CRuntimeClass类型的静态成员变量: 
static const AFX_DATA CRuntimeClass classCView; 

原来RUNTIME_CLASS的作用就是引用由DECLARE_DYNAMIC宏引入的静态成员变 
量。 

2。DECLARE_DYNAMIC(class_name) 
由于篇幅的原因,宏的具体定义代码就不列出来了,感兴趣的可以去看文件 
afx.h。 
该宏往类中声明了三个成员: 
protected: 
static CRuntimeClass* PASCAL _GetBaseClass(); 
public: 
virtual CRuntimeClass* GetRuntimeClass() const; 
static const AFX_DATA CRuntimeClass class##class_name; 

有两个成员函数,一个静态成员变量class+类名,同RUNTIME_CLASS相似,如 
果是DECLARE_DYNAMIC(CView)的话,这个静态成员变量将是classCView。可见这 
个成员变量的名称是和DECLARE_DYNAMIC的参数有关的。在下文我们把这个成员变 
量统统记做class##class_name。 


这个静态成员和两个成员函数在哪里被初始化和具体实现呢?原来是在IMPL 
EMENT_DYNAMIC宏里。 

3。IMPLEMENT_DYNAMIC(class_name, base_class_name) 
查看它的宏定义,如果_AFXDLL被定义了的话,由DECLARE_DYNAMIC引入的成 
员的初始化和实现是这样的: 

CRuntimeClass* PASCAL class_name::_GetBaseClass() 
{ 
return RUNTIME_CLASS(base_class_name); 
} 
CRuntimeClass* class_name::GetRuntimeClass() const 
{ 
return RUNTIME_CLASS(class_name); 
} 
AFX_COMDAT const AFX_DATADEF 
CRuntimeClass class_name::class##class_name = 
{ 
#class_name, 
sizeof(class class_name), 
0xFFFF, 
NULL, 
NULL, 
&class_name::_GetBaseClass, 
NULL 
};//这是在初始化静态成员变量class##class_name。 
//CRuntimeClass结构的各个成员的意义可查看msdn。 


4。_DECLARE_DYNAMIC(class_name) 
该宏的定义和DECLARE_DYNAMIC(class_name)基本一样。不同之处是静态成员 
class##class_name前面没有const修饰符。 

5。DECLARE_DYNCREATE(class_name) 

该宏也往类中引入了DECLARE_DYNAMIC宏所引入的那三个成员。除此之外,它 
还另外引入了一个成员: 
static CObject* PASCAL CreateObject(); 
该宏引入的成员在IMPLEMENT_DYNCREATE里初始化和实现。 

6。IMPLEMENT_DYNCREATE(class_name, base_class_name) 
该宏自然是初始化和实现由DECLARE_DYNCREATE引入的成员了。 
我们看看CreateObject的实现: 
CObject* PASCAL class_name::CreateObject() 
{ 
{ 
return new class_name; 
} 
呵,这个函数是如此简单,它就是用CObject类里重载的new操作符创建一个 
该类类型的对象。 

7。_DECLARE_DYNCREATE(class_name) 
该宏引入了和DECLARE_DYNCREATE引入的四个成员差不多的成员。唯一的区别 
是该宏引入的静态成员class##class_name前面没有const修饰符。 

8。DECLARE_SERIAL(class_name) 
该宏引入了和_DECLARE_DYNCREATE所引入的一样的四个
【YOLOv11多模态涨点改进】独家创新首发| TGRS 2026 |引入 CIFusion 通道交互融合模块,通过跨特征交互机制强化目标区域响应,适合多模态融合目标检测,小目标检测高效涨点 🔥本文提出了一种改进YOLOv11多模态目标检测模型的方法,通过引入CIFusion通道交互融合模块来提升RGB与红外特征融合效果。CIF模块采用通道级自适应交互机制,根据全局上下文动态分配不同模态通道的重要性,实现跨模态特征交互与互补信息融合。相比传统拼接或加权融合方式,CIF能够增强目标区域响应,抑制背景噪声,提高小目标和低对比度目标的检测性能。实验表明,该方法在DroneVehicle等数据集上显著提升了检测精度。论文还详细介绍了CIF模块的结构原理、实现代码及模型配置方法。 阅读详情

相关推荐

无GPS室内飞行:基于PX4与MID360的FAST-LIO定点悬停实战解析

本文详细解析了基于PX4飞控与大疆MID360激光雷达的无GPS室内飞行技术,重点介绍了FAST-LIO算法在定点悬停中的应用。通过硬件配置、软件环境搭建、坐标系转换等实战经验,帮助开发者解决室内定位难题,实现精准悬停与稳定飞行。

weixin_29056781的博客 261

IMPLEMENT_DYNAMIC

IMPLEMENT_DYNAMIC是实现“运行时类型识别”宏,与之相对应的是DECLARE_DYNAMIC(声明“运行时类型识别”宏)。也就是说你在.CPP文件中如果看见有IMPLEMENT_DYNAMIC,则在.H文件中必定有DECLARE_DYNAMIC的声明。  DECLARE_DYNAMIC/DEClARE_DYNAMIC是为了确定运行时对象属于哪一个类而定义的宏。  DEClARE_

记事本 1万+

实战避坑:泛微E9流程接口与单点登录(SSO)开发全解析(含自定义Action、Restful API与免密登录)

本文深入解析泛微E9流程接口与单点登录(SSO)开发中的关键技术与避坑指南,涵盖自定义Action开发、Restful API鉴权机制及跨系统单点登录实现。通过实战案例与代码示例,帮助开发者高效完成二次开发,解决系统集成中的数据孤岛问题,提升企业信息化建设效率。

weixin_42549451的博客 672

二、C++、DECLARE_DYNAMIC与IMPLEMENT_DYNAMIC宏

DECLARE_DYNAMIC:声明“运行时类型识别”宏,存在于.h文件中 语法:DECLARE_DYNAMIC(派生类) IMPLEMENT_DYNAMIC:实现“运行时类型识别”宏,存在于.cpp文件中 语法:DECLARE_DYNAMIC(派生类,基类) 作用:使得在MFC框架下能够运行所建的派生类,此派生类继承于MFC中的基类 ...

ARM_qiao的博客 4132

对计算机专业来说学历真的重要吗?

我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...

启舰 55万+

PLC凸轮开关指令编程应用——控制算法

凸轮开关指令的作用是在PLC程序中根据凸轮开关(Cam Switch)的状态执行不同的操作。凸轮开关通常是机械式的开关装置,它的位置会随着机械运动的变化而改变。凸轮开关的状态可以用来检测机器的位置、角度或其他相关信息,从而触发相应的控制动作。总结起来,凸轮开关指令是PLC编程中常用的一种控制算法,通过检测凸轮开关的状态来触发相应的操作。本文将介绍凸轮开关指令的应用和相应的控制算法,并提供相关的源代码示例。在这个示例中,凸轮开关状态的值代表不同的位置,根据凸轮开关状态的不同,执行相应的动作。

LiJavascript的博客 1034

IMPLEMENT_DYNCREATE

<br />IMPLEMENT_DYNCREATE   <br /><br />IMPLEMENT_DYNCREATE(class_name,base_class_name)   <br />说明:   <br />通过DECLARE_DYNCREATE宏来使用IMPLEMENT_DYNCREATE宏,以允许CObject派生类对象在运行时自动建立。主机使用此功能自动建立对象,例如,但它在串行化过程中从磁盘读去一个对象时,他在类工具里加入IMPLEMENT_DYNCREATE宏。若用户使用DECLARE_D

WINCOL的专栏 4477

直流无刷电机FOC控制算法 理论到实践 —— 实践

关于直流无刷电机FOC控制算法的理论章节,本人已经在前两章进行过详细说明,大家可以自行进行阅读,请务必了解过理论之后再来学习如何具体进行实现。直流无刷电机FOC控制算法 理论到实践 —— 理论(一)直流无刷电机FOC控制算法 理论到实践 —— 理论(二)本章节主要讨论采用MCU微控制器如何具体实现直流无刷电机的FOC控制。

爱出名的狗腿子 1万+

DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC

MPLEMENT_DYNAMIC是实现“运行时类型识别”宏,与之相对应的是DECLARE_DYNAMIC(声明“运行时类型识别”宏)。也就是说你在.CPP文件中如果看见有IMPLEMENT_DYNAMIC,则在.H文件中必定有DECLARE_DYNAMIC的声明。  DECLARE_DYNAMIC/DEClARE_DYNAMIC是为了确定运行时对象属于哪一个类而定义的宏。  DEClARE_D

Arcsinsin的学习笔记 1653

产品路线图的三种模型(RICE/MoSCoW/Kano),教你如何对需求进行优先级排序

RICE/MoSCoW/Kano三种模型,教你如何对需求进行优先级排序。 也许你会让业务提供一份ROI,记得前不久参加过一场立项会评审,一位很有意思的小产品在会上讲不清楚ROI,评审们要求会后重新梳理,小产品表达不要为难业务方干一些他们不擅长的事了。这个看似笑话的经历,背后隐藏着价值判断已经流于形式。 也许你会要求业务方直接给出需求优先级列表,把任务分为P0到P5,这样的划分除了按需求本质的优先级还同时考虑了开发资源、开发难度等问题。毫不夸张地说,我曾经拿到一张全是P0级别的需求清单,如果一切任务都是高

wenyusuran的专栏 5538

海格通信嵌入式面试题及参考答案

计算电路的最高工作频率如何计算? 计算电路的最高工作频率主要考虑电路中的关键路径延迟。关键路径是指在整个电路中,信号传播延迟最长的路径。电路的最高工作频率的倒数就是时钟周期,而时钟周期必须大于关键路径的延迟时间。 首先要确定电路中各个模块的延迟。比如对于组合逻辑电路,可以通过查看芯片手册获取门电路的延迟参数。以一个简单的与门、或门、非门组成的组合逻辑为例,每个门都有自己的传输延迟,把信号从输入到输出经过的所有门的延迟相加,就得到这部分组合逻辑的延迟。 对于包含寄存器的电路,还需要考虑寄

大模型大数据攻城狮的专栏 1271

宏DECLARE_DYNCREATE与DECLARE_DYNAMIC

一、MSDN的解释 启用 CObject对象 --将动态创建的派生类在运行时。 DECLARE_DYNCREATE(class_name ) 目的:使每个CObject的对象在运行的时候具备动态创建的能力,Application Farmework框架利用这种能力来创建对象。 例如,创建的新视图,当您打开新文档。 文档,查看,并且,框架类应支持动态创建,因为框架需要动态创建它们。 h ,模块中加入DECLARE_DYNCREATE宏,然后在每个需要访问这个类的对象的 .cpp 文件中包含这个模块.

sinat_31608641的博客 2027

如何卸载Gazebo与重装

gazebo是一款关于车辆和无人机的仿真软件,本文大致介绍它是何物,以及他的安装和卸载方法,对于ROS开发者,本文有一定参考意义。

gongdiwudu的专栏 1万+

DECLARE_DYNCREATE(DECLARE_DYNAMIC)与IMPLEMENT_DYNCREATE(IMPLEMENT_DYNAMIC)解析

随便搜索一下,发现给出的解释是在运行期让派生类支持动态创建,可是给出详细解释的却很少,那么下面仔细看看此宏的扩展: #define DECLARE_DYNCREATE(class_name) \ DECLARE_DYNAMIC(class_name) \ static CObject* PASCAL CreateObject(); #define _DECLAR

waxgourd0的专栏 5966

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏的详细解释

原文: http://blog.chinaunix.net/uid-26881496-id-3175819.html ECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏的详细解释 最近有些朋友在看《深入浅出MFC》的时候,被第三章的几个宏给卡住了,记得我第一次看此书时,也被这几个宏给卡住。当然真正卡人的其实是第一个,也就是 DECLARE_DYNAMIC/IMPLEMENT_D

痞子 803

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

DECLARE_DYNCREATE,IMPLEMENT_DYNCREATE和DECLARE_DYNAMIC,IMPLEMENT_DYNAMIC 的差异

书籍:《Visual C++ 2017从入门到精通》环境:Visual Studio 2022内容:[例8.19]AfxBeginThread创建用户界面线程在 MFC(Microsoft Foundation Classes)中,和是用于支持 ​​ 和 ​​ 的关键宏。

felicity_one的博客 933

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏

第一次接触DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC这个宏一头雾水,特别在MFC深入浅出的时候遇到它,完全不明白它是做什么的,在此学习一下: #define DECLARE_DYNAMIC(class_name) \public: \ static CRuntimeClass class##class_name; \ virtual CRuntim

iloveyou418的博客 897

DECLARE_DYNAMIC

DECLARE_DYNAMIC 宏的含义  DECLARE_DYNAMIC(class_name)   说明:    但从CObject派生一个类时,此宏增加关于一个对象类的访问运行时间功能。把DECLARE_DYNAMIC宏加入类的头文件中,然后在全部需要访 问词类对象的.CPP文件中都包含此模块。如果像所描述那样使用DELCARE_DYNAMIC和IMPLEMENT_DYNAMIC宏,那么用户便可使 用RUNTIME_CLASS宏和CObject::IsKindOf函数以在运行时间决定对象类。如果DEC

lost_forget的专栏 6128

VC中DELCLARE_DYNAMIC和IMPLEMENT_DYNAMIC宏的完整含意和用法

MFC为了达到RTTI的功能实现使用了CRunTimeClass类,该类记录必要的信息,以便建立型录,用链表来实现,CRunTimeClass的成员变量类的名称,链表的First指针和Next指针。       MFC为了把CRunTimeClass放进类中,就主要使用了DELCLARE_DYNAMIC和IMPLEMENT_DYNAMIC宏。   #define RUNTIME_CLASS(

guoduhua的专栏 3497

DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC宏

    IMPLEMENT_DYNAMIC是实现“运行时类型识别”宏,与之相对应的是DECLARE_DYNAMIC(声明“运行时类型识别”宏)。也就是说你在.CPP文件中如果看见有IMPLEMENT_DYNAMIC,则在.H文件中必定有DECLARE_DYNAMIC的声明。 DECLARE_DYNAMIC/DEClARE_DYNAMIC是为了确定运行时对象属于哪一个类而定义的宏。 DEClARE_

52yyp的专栏 4万+

DECLARE_DYNCREATE,IMPLEMENT_DYNCREATE和DECLARE_DYNAMIC,IMPLEMENT_DYNAMIC 可以互换使用吗?

书籍:《Visual C++ 2017从入门到精通》环境:Visual Studio 2022内容:[例8.19]AfxBeginThread创建用户界面线程在 MFC(Microsoft Foundation Classes)中,和是两组功能不同的宏,​不可互换使用​​。

felicity_one的博客 676

DECLARE_DYNAMIC()与IMPLEMENT_DYNAMIC()

MFC六大关键技术之(二)——运行时类型识别(RTTI) 运行时类型识别(RTTI)即是程序执行过程中知道某个对象属于某个类,我们平时用C++编程接触的RTTI一般是编译器的RTTI,即是在新版本的VC++编译器里面选用“使能RTTI”,然后载入typeinfo.h文件,就可以使用一个叫typeid()的运算子,它的地位与在C++编程中的sizeof()运算子类似的地方(包含一个头文件,

clayruan的专栏 2540

DECLARE_DYNCREATE(DECLARE_DYNAMIC)与IMPLEMENT_DYNCREATE(IMPLEMENT_DYNAMIC)

主要用于支持RTTI。你可以根据你的需求选择适当的宏组合来满足你的类的需求。看源码,发现这两组宏的实现是有细微差别的,需要配合使用。主要用于支持对象的动态创建和RTTI,而。

sinat_31608641的博客 553
上一篇: [jsp]Class.forName详解
下一篇: 【java.repaint】制作动画时的刷新
Smile_安之
博客等级 码龄14年 21粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值