MFC原理第四讲.动态创建机制

一丶要学习的知识点以及简介

  动态创建是什么意思?

    动态创建其实就是跟C++的new一样.都是创建对象.但是规避了C++语法的缺陷.

例如:

    char * ClassName = "CMyApp"

    CObject *obj = new ClassName;

C++ 中不允许这样编写代码

要学习的知识点

    1.DECLARE_DYNCREATE 宏   学过上讲RTTI的应该明白.这个就是个文字替换. 也可以说这个宏是一个声明宏 当然也有实现宏

    2.IMPLEMENT_DYNCREATE

还需要了解CRuntimeClass 结构. 支持动态创建的成员.

 

struct CRuntimeClass
{ LPCSTR m_lpszClassName; 类名
int m_nObjectSize; 类大小
UINT m_wSchema; 类编号
CObject* (PASCAL* m_pfnCreateObject)(); 存放支持动态创建的类 CRuntimeClass* m_pBaseClass; // Operations
CObject* CreateObject(); 动态创建函数
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; 判断函数 ...
CRuntimeClass* m_pNextClass; 链表存储执向下一个 };

二丶如何使用动态创建.

  支持动态创建的是跟窗口有关的. 也就是CFrameWnd类. 如果我们继承了这个类.我们也可以让他支持动态创建.

  1.添加声明宏

  2.添加实现宏

  3.动态创建使用.

添加声明宏 则添加到我们继承CFrameWnd类中即可. 实现宏则在外边

 参数填写自己的类名

添加实现宏

使用动态创建. 在InitInstance里面使用即可.我们的new 窗口改成动态创建即可.

RUNTIME_CLASS宏可以拆解开.

m_pMainWnd = (CMainWnd *)((CRuntimeClass*)(&CMainWnd::classCMainWnd))->CreateObject();

应用程序实现截图:

三丶动态创建实现原理 之 宏  拆开

   我们要看实现原理.当然要把宏拆看看看做了什么事情了.

1. DECLARE_DYNCREATE 宏拆开

#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \ RTTI动态识别
static CObject* PASCAL CreateObject();

我们可以看到这个宏 包含了我们的RTTI 类型识别. 并且添加了一个新的 成员函数

static Cobject * Createobject();

RTTI动态识别.上一讲已将讲过了. 就是添加了一个 CRuntimeClass 成员.以及获取成员的方法. 本次不讲解.

全部解开的宏

public:
static const CRuntimeClass classCMainWnd; 指针
virtual CRuntimeClass* GetRuntimeClass() const; 获取这个指针的函数 static CObject* PASCAL CreateObject(); 新增的函数

2.实现宏拆开 IMPLEMENT_DYNCREATE

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject, NULL) 其中还包含了一个宏 IMPLEMENT_RUNTIMECLASS
也进行拆开.
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \
AFX_COMDAT const CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
RUNTIME_CLASS(base_class_name), NULL, class_init }; \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); }

第一个宏 IMPLEMENT_DYNCREATE 其实就是对 CreateObject进行实现. 也就是返回自己本身的 创建的类

第二个宏就是对 自己本身的结构体成员进行初始化.并且实现虚函数获取自己的这个成员. 跟RTTI一样.只不过初始化的时候.结构体初始化的值不一样.也就是我们上面说的CRuntimeClass结构中的新增的两个

成员进行了赋值.

解析的代码

  

//IMPLEMENT_DYNCREATE(CMainWnd,CFrameWnd)

CObject* PASCAL CMainWnd::CreateObject()
{
return new CMainWnd;
} const CRuntimeClass CMainWnd::classCMainWnd =
{
"CMainWnd", sizeof(class CMainWnd), 0xFFFF, CMainWnd::CreateObject, 添加了自己的成员函数指针.其余地方一样 这个函数指针创建自己本身对象并且返回.
RUNTIME_CLASS(CFrameWnd), NULL, NULL
};
CRuntimeClass* CMainWnd::GetRuntimeClass() const
{
return RUNTIME_CLASS(CMainWnd);
}

所以远离就是CRuntime里面添加自己创建对象的函数指针. 然后自己的类中实现这个函数.创建自己的对象并且返回

这个就是动态创建了.

MFC原理第四讲.动态创建机制的更多相关文章

  1. MFC原理第六讲.消息传递

    ---恢复内容开始--- MFC原理第六讲.消息传递 一丶简介 通过上一讲我们的消息映射表.我们得知. 消息映射表 会保存父类的MessageMap 以及自己当前的消息结构体数组. 消息传递是一层一层 ...

  2. Springboot定时任务原理及如何动态创建定时任务

    一.前言 上周工作遇到了一个需求,同步多个省份销号数据,解绑微信粉丝.分省定时将销号数据放到SFTP服务器上,我需要开发定时任务去解析文件.因为是多省份,服务器.文件名规则.数据规则都不一定,所以要做 ...

  3. [转载] java的动态代理机制详解

    转载自http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代 ...

  4. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  5. java的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  6. Java的动态代理机制详解(转)

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  7. (转)java的动态代理机制详解

    原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一 ...

  8. InvocationHandler和Proxy(Class)的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  9. 【Java深入研究】5、Proxy动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

随机推荐

  1. .net读取excel数据到DataSet中

    Dim objExcelFile As Excel.Application Dim objWorkBook As Excel.Workbook Dim objSheet As Excel.Worksh ...

  2. Cookie的使用(14)

    一:cookie的简要介绍: (1)什么是cookie a.cookie是一种客户端的状态管理技术b.当浏览器向服务器发送请求的时候,服务器会将少量的数据以set-cookie消息头的方式发送给浏览器 ...

  3. navicat连接mysql出现2059错误

    最近在学习django的时候需要用到数据库,于是便下载了navicat准备和mysql配套使用,但是在连接的时候确出现了如下问题: 网上查询过后,发现这个错误出现的原因是在mysql8之前的版本中加密 ...

  4. centos7安装mariadb

    ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 1.官方um安装mariadb 1).准备官方yum [mariadb ...

  5. java.lang.RuntimeException: Invalid action class configuration that references an unknown class name

    ---恢复内容开始--- 转自 : https://www.cnblogs.com/javawebsoa/archive/2013/05/25/3098190.html java.lang.Runti ...

  6. jupyter notebook常用快捷键

    阅读目录 命令模式 (按键 Esc 开启) 编辑模式 ( Enter 键启动) Jupyter Notebook 的快捷键 使用前需要进行安装: pip install jupyter   (前提是你 ...

  7. List、Set、数据结构、Collections

    一.数据结构: 1.什么是数据结构: 一种数据的存储方式 2.常见的4+1种数据结构 堆栈结构: 它是只有一个开口的容器结构 特点: 先进后出(FILO) 例子:弹夹,桶装可比克 队列结构: 它是两端 ...

  8. MAC OS 更新GIT版本时遇到的问题

    在更新git版本时,没有备份就删掉了原先的版本,在安装完2.18.0的新版本后,使用命令行git --version,返回错误git not a developer tool or in PATH. ...

  9. FPGA计算中定标与位扩展的实现

    我不知道名字取对没有,在FPGA计算中有时往往需要在不溢出的情况下将数扩大,从而获得更好的计算精度. 比如.在一个8位宽的系统中,将x=0000_0010,算术左移m=5位之后得到xt=0100_00 ...

  10. 疑难杂症:Java中Scanner连续获取int和String型发生错误.

    使用Scanner类获取输入,连续获取int类型和String类型数据时候,发生错误. Scanner sc = new Scanner(System.in); System.out.println( ...