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. mac 清理

    1.iOS DeviceSupport   -- ~/Library/Developer/Xcode/iOS DeviceSupport 这个可重新生成!在连接旧设备调试时,会重新自动生成. 2.iP ...

  2. python random库

    random模块 >>> import random #随机小数 >>> random.random() # 大于0且小于1之间的小数 0.766433866365 ...

  3. 《代码不朽:编写可维护软件的10大要则(C#版)》读后感

    本书作者Joost Visser,译者张若飞.本书讲解了编写可维护代码的10个要则,从目录就可以看出这10点分别是: 编写短小的代码单元(15行以内,在大部分情况下还是能实现的,但是当我们使用Linq ...

  4. Mysql相关存储函数,函数,游标

    https://www.cnblogs.com/zhanglei93/p/6437867.html >>>>请进入

  5. 玩玩微信公众号Java版之七:自定义微信分享

    前面已经学会了微信网页授权,现在微信网页的功能也可以开展起来啦! 首先,我们先来学习一下分享,如何在自己的页面获取分享接口及让小伙伴来分享呢? 今天的主人公: 微信 JS-SDK, 对应官方链接为:微 ...

  6. 用clock()函数计时的坑

    程序中经常用time()函数来返回当前系统时间的秒数,来计时或计算时间差.如果需要用到更高精度的时间,就会自然想到用clock()函数.想当然的认为它返回从程序开始tick数,用clock()/CLO ...

  7. display:inline-block; 在css中是什么意思?

    inline-block主要的用处是用来处理行内非替换元素的高宽问题的!行内非替换元素,比如span.a等标签,正常情况下士不能设置宽高的,加上该属性之后,就可以触发让这类标签表现得如块级元素一样,可 ...

  8. jQuery 基础语法

    jQuery介绍 1.jQuery是一个轻量级的.兼容多浏览器的JavaScript库. 2.jQuery使用户能够更方便地处理HTML Document.Events.实现动画效果.方便地进行Aja ...

  9. tcp/ip 三次握手和4次挥手

    TCP连接两个端口,谁也发起请求,谁就是client端A,另外一个接受请求的server端B.第一次握手:A向B发一个链接请求,带一个seq = x,SYN= x. 第二次握手:B收到链接请求之后向A ...

  10. SSAS 内部错误:操作未能成功

    错误 -1056964601 : 内部错误: 操作未能成功,已终止. HY0008 是数据源的问题,设置数据源的虚拟连接就可以了