最最基本的框架宏使用RUNTIME_CLASS DECLARE_DYNAMIC IMPLEMENT_RUNTIMECLASS
Demo.h
// 简化封装
// 部分的内容在MFC中都是固化的,所以理解并加以记忆是必要的
//
#pragma once
#include <windows.h>///
// 调试支持
#define AfxDebugBreak() _asm { int 3 }
#ifdef _DEBUGvoid __cdecl AfxTrace(LPCTSTR lpszFormat, ...);#define TRACE ::AfxTrace#define ASSERT(f) \if (!(f)) \AfxDebugBreak();#define VERIFY(f) ASSERT(f)#else // _DEBUG#define ASSERT(f) ((void)0)
#define VERIFY(f) ((void)(f))
inline void __cdecl AfxTrace(LPCTSTR, ...) { }
#define TRACE (void)0#endif // _DEBUG// 宏定义// class_name前必须有 #
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \const CRuntimeClass class_name::class##class_name = \{ \#class_name, \sizeof(class class_name), \wSchema, \pfnNew, \RUNTIME_CLASS(base_class_name), \NULL \}; \CRuntimeClass* class_name::GetRuntimeClass() const { return RUNTIME_CLASS(class_name); }// RUNTIME_CLASS宏用来取得class_name类中CRuntimeClass结构的地址
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)&class_name::class##class_name)// no支持动态创建的宏
#define DECLARE_DYNAMIC(class_name) \
public: \static const CRuntimeClass class##class_name; \virtual CRuntimeClass* GetRuntimeClass() const; #define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)// 支持动态创建的宏
#define DECLARE_DYNCREATE(class_name) \DECLARE_DYNAMIC(class_name) \static CObject* __stdcall CreateObject();#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \CObject* __stdcall class_name::CreateObject() \{ return new class_name; } \IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF,class_name::CreateObject)class CObject;struct CRuntimeClass
{// 属性(Attributes)LPCSTR m_lpszClassName; // 类的名称int m_nObjectSize; // 类的大小UINT m_wSchema; // 类的版本号CObject* (__stdcall* m_pfnCreateObject)(); // 创建类的函数的指针CRuntimeClass* m_pBaseClass; // 其基类中CRuntimeClass结构的地址// 操作(operations)CObject* CRuntimeClass::CreateObject(){if(m_pfnCreateObject == NULL)return NULL;return (*m_pfnCreateObject)(); }BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const{const CRuntimeClass* pClassThis = this;while(pClassThis != NULL){if(pClassThis == pBaseClass) // 判断标识类的CRuntimeClass的首地址是否相同return TRUE;pClassThis = pClassThis->m_pBaseClass;}return FALSE; }CRuntimeClass* m_pNextClass; // 将所有CRuntimeClass对象用简单链表连在一起
};class CObject
{
public:virtual CRuntimeClass* CObject::GetRuntimeClass() const{return RUNTIME_CLASS(CObject);}inline CObject::~CObject() { }// 属性(Attibutes)
public:BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const{CRuntimeClass* pClassThis = GetRuntimeClass();return pClassThis->IsDerivedFrom(pClass);}// 实现(implementation)
public:static const CRuntimeClass classCObject;
};const struct CRuntimeClass CObject::classCObject = { "CObject", sizeof(CObject), 0xFFFF,NULL, NULL, NULL};
</pre><pre>
Demo.cpp
//
// 多多调试
// 为了理解MFC的框架
// 了解几个类细微的不同之处
//
#include "Demo.h"class CPersonA : public CObject
{
public: static const CRuntimeClass classCPersonA;virtual CRuntimeClass* GetRuntimeClass() const{ return RUNTIME_CLASS(CPersonA); }
};
const CRuntimeClass CPersonA::classCPersonA = {"CPersonA", sizeof(CPersonA), 0xFFFF, NULL,RUNTIME_CLASS(CObject), NULL };class CPersonB : public CObject
{
public:static const CRuntimeClass classCPersonB;virtual CRuntimeClass* GetRuntimeClass() const{ return RUNTIME_CLASS(CPersonB); } static CObject* __stdcall CreateObject() { return new CPersonB; }
};
const CRuntimeClass CPersonB::classCPersonB = {"CPersonB", sizeof(CPersonB), 0xFFFF, NULL,RUNTIME_CLASS(CObject), NULL };class CPersonEA : public CObject
{DECLARE_DYNAMIC(CPersonEA)
};
IMPLEMENT_DYNAMIC(CPersonEA, CObject)class CPersonEB : public CObject
{DECLARE_DYNCREATE(CPersonEB)
};
IMPLEMENT_DYNCREATE(CPersonEB, CObject)void func1();void func2();void func3();void func4();void main()
{func1();func2();func3();func4();
}void func1()
{CObject* pMyObject = new CPersonA; if(pMyObject->IsKindOf(RUNTIME_CLASS(CPersonA))){CPersonA* pMyPerson = (CPersonA*)pMyObject;delete pMyPerson;}else{delete pMyObject;}
}
void func2()
{CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CPersonB);// 取得了pRuntimeClass指针,不用知道类的名字就可以创建该类CObject* pObject = pRuntimeClass->CreateObject();if(pObject != NULL && pObject->IsKindOf(RUNTIME_CLASS(CPersonB))){delete pObject;}
}
void func3()
{CObject* pMyObject = new CPersonEA; if(pMyObject->IsKindOf(RUNTIME_CLASS(CPersonEA))){CPersonEA* pMyPerson = (CPersonEA*)pMyObject;delete pMyPerson;}else{delete pMyObject;}
}
void func4()
{CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CPersonEB);// 取得了pRuntimeClass指针,不用知道类的名字就可以创建该类CObject* pObject = pRuntimeClass->CreateObject();if(pObject != NULL && pObject->IsKindOf(RUNTIME_CLASS(CPersonEB))){delete pObject;}
}
最最基本的框架宏使用RUNTIME_CLASS DECLARE_DYNAMIC IMPLEMENT_RUNTIMECLASS相关推荐
- VC/MFC中常用宏的含义
VC/MFC中常用宏的含义 Visual C++ MFC 中常用宏的含义(转载) AND_CATCHAND_CATCH AND_CATCH(exception_class,exception ...
- VC宏定义 及常用宏定义说明
1. 宏定义的格式 宏定义的一般格式是: #define 标识符 字符串 其中,标识符和字符串之间用空格隔开.标识符又称宏名,为了区别于一般变量,通常用英文大写字母表示:字符串又称宏体,可以是常 ...
- Nature Methods:宏基因组物种组成分析工具MetaPhlAn2
文章目录 宏基因组物种组成分析工具MetaPhlAn2 导读 主要结果 图1:MetaPhlAn2可以准确地重建鸟枪法宏基因组的分类组成 Reference 扩展阅读 猜你喜欢 写在后面 宏基因组物种 ...
- 学习C++项目—— 搭建多进程网络服务框架,增加业务和日志,心跳机制
学习计算机网络编程 一.思路和学习方法 本文学习于:C语言技术网(www.freecplus.net),在 b 站学习于 C 语言技术网,并加以自己的一些理解和复现,如有侵权会删除. 接下来对 ...
- 开源的app后台开源框架汇总
1.app-engine 参考网址: 1. https://github.com/sofn/app-engine 2. https://www.oschina.net/p/app-engine ap ...
- 综述:本专栏将介绍以下内容(专栏:最笨的办法学SSM框架)
虽说在公司做项目开发过程中,我们不需要总是从头开始搭建SSM(Spring+SpringMVC+Mybatis)框架,我们总是专注于业务逻辑,但是框架的学习才能真正提高我们的能力. 本人学习总是用最笨 ...
- MFC 教程【3_CObject类】
CObject类 CObject是大多数MFC类的根类或基类.CObject类有很多有用的特性:对运行时类信息的支持,对动态创建的支持,对串行化的支持,对象诊断输出,等等.MFC从CObject派生出 ...
- 读书笔记 来自网络
2010年3月15日 # <深入解析MFC>笔记 12. 进程与线程 2009-10-7 ======================= <深入解析MFC>笔记 12. 进程与 ...
- MFC之RTTI分析(基于侯俊杰的《深入浅出MFC》)
2019独角兽企业重金招聘Python工程师标准>>> MFC框架早在标准C++之间提出并实现了类的运行时识别(RTTI)功能,下面记录下基于我对其的理解. 要实现RTTI必须在定义 ...
最新文章
- python02-条件语句到循环语句
- linux db2乱码,DB2乱码(开始和结束,字符串中间没有好的办法)
- 当容器应用越发广泛,我们又该如何监测容器?
- 重磅!这个 GitHub 汇总了 300 道 Python 面试题!
- 面试官:GET和POST两种基本请求方法有什么区别
- 用 CSS 实现元素垂直居中,有哪些好的方案?
- 2016 年 ACM/ICPC 青岛区域赛 Problem C Pocky
- SQL_EXEC_ID分析(转帖)
- 激活函数active function
- AP类WiFi模块系列二:半成品主板式大功率AP类WiFi模块
- android webview 文件下载,Android编程使用WebView实现文件下载功能的两种方法
- lisp边长注记_小程序cad批量注记建筑物边长
- java阶梯计费,机器智能审核阶梯计费方式
- 全自动化处理每月缺卡数据,输出缺卡人员信息
- “古董级” 诺基亚功能机跑Linux是怎样的画风?
- html程序产品目录,产品目录(Catalog)制作大师
- 看纷享销客如何布局连接型CRM
- PowerShell 中的目录文件管理
- python 画曲线(基本的坐标轴,刻度,网格,解决中文显示乱码)
- 从理论到实战!视频流车辆计数和目标跟踪
热门文章
- php larve,封装composer包,实现thinkphp、larverl、yii框架中使用(使用框架实现回调方法)...
- python串口连续数据_Python代码从串口连续接收可变数据
- GB28181平台介绍
- 【520有奖征文】 老同学聚会,20年IT行业从业感悟
- centso7.5 安装minconda3和创建项目所需python3环境
- 吴恩达深度学习2.3笔记_Improving Deep Neural Networks_超参数调试 和 Batch Norm
- 【带着canvas去流浪(5)】绘制K线图
- Python实例:通过字典某个关键字排序
- java的接口和抽象类区别
- Huge page使用的一些问题