当前位置: 首页 > news >正文

MFC程序设计(七)运行时类信息机制

运行时类信息机制的作用

我们在创建对象时,自己是清楚对象属于哪个类,但是计算机却不清楚。而MFC运行时类信息机制就是解决这个问题而存在的

运行时类信息机制的使用

我们在创建一个类时,只有满足以上三个条件,该类才能支持运行时类信息机制 

代码验证

#include<afxwin.h>
#include<iostream>
class CAnimal : public CObject
{DECLARE_DYNAMIC(CAnimal);
};
IMPLEMENT_DYNAMIC(CAnimal, CObject)class CDog : public CAnimal
{DECLARE_DYNAMIC(CDog);
};
IMPLEMENT_DYNAMIC(CDog, CAnimal)int main()
{CDog yellowdog;if (yellowdog.IsKindOf(RUNTIME_CLASS(CDog))){std::cout << "yellowdog is CDog" << std::endl;}else{std::cout << "yellowdog is not CDog" << std::endl;}return 0;
}

程序运行,我们发现计算机判断结果是对象yellowdog属于CDog类。

代码修改为判断yellowdog是否属于CAnimal类时,计算机判断结果是对象yellowdog也属于CAnimal类

代码修改为判断yellowdog是否属于CWnd类时,计算机判断结果是对象yellowdog不属于CWnd类

而计算机判断对象是否属于某个类,依据就是上文的三个条件

运行时类信息机制的解析

宏展开

接下来我们展开上文中CDog中实现运行时类信息机制的两个宏,观察该机制是如何工作的

//DECLARE_DYNAMIC(CDog)宏展开
public: static const CRuntimeClass classCDog; //静态的结构体virtual CRuntimeClass* GetRuntimeClass() const; //虚函数//IMPLEMENT_DYNAMIC(CDog,CAnimal)宏展开
IMPLEMENT_RUNTIMECLASS(CDog, CAnimal, 0xFFFF, NULL, NULL)//IMPLEMENT_RUNTIMECLASS(CDog, CAnimal, 0xFFFF, NULL, NULL)宏展开
AFX_COMDAT const CRuntimeClass CDog::classCDog = 
{ "CDog", //类名称sizeof(class CDog), //类大小0xFFFF, //类版本 0xFFFFNULL, //动态创建机制使用,这里为NULL//RUNTIME_CLASS(CAnimal), 这也是一个宏,如下是宏展开的样子((CRuntimeClass*)(&CAnimal:classCAnimal)), //返回父类静态结构体的地址NULL,//不使用为NULLNULL //不使用为NULL
}; CRuntimeClass* CDog::GetRuntimeClass() const 
{ //return RUNTIME_CLASS(CDog); 这也是一个宏,如下是宏展开的样子return ((CRuntimeClass*)(&CDog::classCDog));//返回头节点
}struct CRuntimeClass//CRuntimeClass结构体信息如下所示
{LPCSTR m_lpszClassName;					//类名称int m_nObjectSize;						//类大小UINT m_wSchema; 						//类版本CObject* (PASCAL* m_pfnCreateObject)(); //动态创建才会使用 暂时NULL函数指针CRuntimeClass* m_pBaseClass;			//父类信息CRuntimeClass* m_pNextClass;      		//NULLconst AFX_CLASSINIT* m_pClassInit;		//NULL
}

宏展开各部分作用

如下是IMPLEMENT_DYNAMIC()展开后样子

如图所示,子类指向父类,这又是一个链表

执行过程 

通过遍历上图所示的链表来检查类对象属于哪个类

接下来我们以yellowdog.IsKindOf(RUNTIME_CLASS(CDog))为例讲解整个执行过程

yellowdog.IsKindOf(RUNTIME_CLASS(CDog))//函数内部this为&yellowdog,参数为链表头
{CRuntimeClass* pClassThis = GetRuntimeClass();//利用&yellowdog调用宏展开的虚函数,获取链表头结点classCDogreturn pClassThis->IsDerivedFrom(RUNTIME_CLASS(CDog))//函数内部this和参数都是链表头classCDog{const CRuntimeClass* pClassThis = this;//获取链表头classCDog while (pClassThis != NULL){if (pClassThis == RUNTIME_CLASS(CDog))return TRUE;pClassThis = pClassThis->m_pBaseClass;}return FALSE;}
}

相关文章:

MFC程序设计(七)运行时类信息机制

运行时类信息机制的作用 我们在创建对象时&#xff0c;自己是清楚对象属于哪个类&#xff0c;但是计算机却不清楚。而MFC运行时类信息机制就是解决这个问题而存在的 运行时类信息机制的使用 我们在创建一个类时&#xff0c;只有满足以上三个条件&#xff0c;该类才能支持运行时…...

fflush的概念和使用案例

fflush() 是C语言标准库中用于控制输入/输出缓冲区的函数&#xff0c;其主要功能是强制刷新缓冲区&#xff0c;确保数据及时写入目标设备&#xff08;如屏幕、文件&#xff09;。以下是其概念和典型使用场景&#xff1a; 概念 功能&#xff1a; 刷新指定流的缓冲区。对于输出流…...

嵌入式知识点总结 操作系统 专题提升(四)-上下文

针对于嵌入式软件杂乱的知识点总结起来&#xff0c;提供给读者学习复习对下述内容的强化。 目录 1.上下文有哪些?怎么理解? 2.为什么会有上下文这种概念? 3.什么情况下进行用户态到内核态的切换? 4.中断上下文代码中有哪些注意事项&#xff1f; 5.请问线程需要保存哪些…...

React 封装高阶组件 做路由权限控制

React 高阶组件是什么 官方解释∶ 高阶组件&#xff08;HOC&#xff09;是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分&#xff0c;它是一种基于 React 的组合特性而形成的设计模式。 高阶组件&#xff08;HOC&#xff09;就是一个函数&…...

【实践案例】基于大语言模型的海龟汤游戏

文章目录 项目背景提示词构建海龟汤主持人真相判断专家 具体实现流程文心一言大语言模型“海龟汤”插件参考 项目背景 “海龟汤”作为一种聚会类桌游&#xff0c;又称情境推理游戏&#xff0c;是一种猜测情境还原事件真相的智力游戏。其玩法是由出题者提出一个难以理解的事件&…...

NeetCode刷题第20天(2025.2.1)

文章目录 106 Best Time to Buy and Sell Stock with Cooldown 使用 Cooldown 买卖股票的最佳时间107 Coin Change II 换币 II108 Target Sum 目标总和109 Interleaving String 交错字符串110 Edit Distance 编辑距离111 Maximum Subarray 最大子数组112 Jump Game 跳跃游戏113…...

DeepSeek:人工智能领域的革新者与未来展望

在当今这个数据驱动的时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度发展&#xff0c;而DeepSeek作为这一领域的先锋&#xff0c;正引领着AI技术的创新与突破。作为一家致力于推动人工智能技术创新与应用的前沿企业&#xff0c;DeepSeek不仅在多语言编…...

Spring Bean 容器

技术成长&#xff0c;是对场景设计细节不断的雕刻&#xff01; 你觉得自己的技术什么时候得到了快速的提高&#xff0c;是CRUD写的多了以后吗&#xff1f;想都不要想&#xff0c;绝对不可能&#xff01;CRUD写的再多也只是能满足你作为一个搬砖工具人&#xff0c;敲击少逻辑流…...

Flask代码审计实战

文章目录 Flask代码审计SQL注入命令/代码执行反序列化文件操作XXESSRFXSS其他 审计实战后记reference Flask代码审计 SQL注入 1、正确的使用直白一点就是&#xff1a;使用”逗号”&#xff0c;而不是”百分号” stmt "SELECT * FROM table WHERE id?" connectio…...

springboot启动配置文件-bootstrap.yml常用基本配置

在Spring Boot应用程序中&#xff0c;bootstrap.yml文件通常用于配置应用程序的启动阶段。在这个文件中&#xff0c;你可以配置一些在应用程序启动之前需要加载的属性&#xff0c;例如外部配置源、加密属性等。以下是一些常用的基本配置项&#xff1a; 1. 外部配置源 1.1 配置…...

2月3日星期一今日早报简报微语报早读

2月3日星期一&#xff0c;农历正月初六&#xff0c;早报#微语早读。 1、多个景区发布公告&#xff1a;售票数量已达上限&#xff0c;请游客合理安排行程&#xff1b; 2、2025春节档总票房破70亿&#xff0c;《哪吒之魔童闹海》破31亿&#xff1b; 3、美宣布对中国商品加征10…...

如何确认Linux嵌入式系统的触摸屏对应的是哪个设备文件(/dev/input/event1)?如何查看系统中所有的输入设备?输入设备的设备文件有什么特点?

Linux嵌入式系统的输入设备的设备文件有什么特点&#xff1f; 在 Linux 中&#xff0c;所有的输入设备&#xff08;如键盘、鼠标、触摸屏等&#xff09;都会被内核识别为 输入事件设备&#xff0c;并在 /dev/input/ 目录下创建相应的 设备文件&#xff0c;通常是&#xff1a; …...

FFmpeg:多媒体处理的瑞士军刀

FFmpeg&#xff1a;多媒体处理的瑞士军刀 前言 FFmpeg 是一个功能强大且跨平台的开源多媒体框架&#xff0c;广泛应用于音视频处理领域。 它由多个库和工具组成&#xff0c;能够处理各种音视频格式&#xff0c;涵盖编码、解码、转码、流处理等多种操作。 无论是专业视频编辑…...

电控三周速成计划参考

第1周&#xff1a;基础搭建与GPIO控制 学习目标&#xff1a;建立开发环境&#xff0c;掌握最基础的硬件控制能力 每日学习&#xff08;2-3小时&#xff09;&#xff1a; 环境搭建&#xff08;2天&#xff09; 安装Keil MDK-ARM STM32CubeMX使用CubeMX创建第一个工程&#xf…...

Ubuntu修改配置文件--编辑操作

例如。 1.打开 /etc/samba/smb.conf 该配置文件&#xff1a; sudo vi /etc/samba/smb.conf 2.当你运行sudo vi /etc/samba/smb.conf命令后&#xff0c;你需要按i键进入插入模式&#xff08;Insert Mode&#xff09;。这时&#xff0c;在屏幕底部你应该能看到“-- INSERT --”…...

2021版小程序开发5——小程序项目开发实践(1)

2021版小程序开发5——小程序项目开发实践(1) 学习笔记 2025 使用uni-app开发一个电商项目&#xff1b; Hbuidler 首选uni-app官方推荐工具&#xff1a;https://www.dcloud.io/hbuilderx.htmlhttps://dev.dcloud.net.cn/pages/app/list 微信小程序 管理后台&#xff1a;htt…...

二分/双指针/单调栈队列专题

1.4924. 矩阵 - AcWing题库 一开始打表找规律以为是右上角向左下角递增,但当n很大的时候就不对了,因此我们得去观察 i * i 100000 * (i - j) j * j i * j 这个式子,我们关心的是这个式子的单调性因此我们可以分别将i和j看作常数来对式子进行求导,可以得到 f(i) 2 * i 10…...

XCCL、NCCL、HCCL通信库

XCCL提供的基本能力 XCCL提供的基本能力 不同的XCCL 针对不同的网络拓扑&#xff0c;实现的是不同的优化算法的&#xff08;不同CCL库最大的区别就是这&#xff09; 不同CCL库还会根据自己的硬件、系统&#xff0c;在底层上面对一些相对应的改动&#xff1b; 但是对上的API接口…...

【Deep Seek本地化部署】模型实测:规划求解python代码

目录 前言 一、实测 1、整数规划问题 2、非线性规划问题 二、代码正确性验证 1、整数规划问题代码验证 2、非线性规划问题代码验证 三、结果正确性验证 1、整数规划问题结果正确性验证 2、非线性规划问题正确性验证 四、整数规划问题示例 后记 前言 模型&#xff…...

MySQL锁类型(详解)

锁的分类图&#xff0c;如下&#xff1a; 锁操作类型划分 读锁 : 也称为共享锁 、英文用S表示。针对同一份数据&#xff0c;多个事务的读操作可以同时进行而不会互相影响&#xff0c;相互不阻塞的。 写锁 : 也称为排他锁 、英文用X表示。当前写操作没有完成前&#xff0c;它会…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...