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. Newtonsoft.Json 时间格式化

    时间序列化经常多个T:“2017-01-23T00:00:00” 解决方案: 日期格式化输出,指定IsoDateTimeConverter的DateTimeFormat即可 IsoDateTimeCo ...

  2. Turtle库的建立——汉诺塔

    Turtle库的建立——汉诺塔 1.首先是要用递归方法来完成这个汉诺塔法则 2.其次,就要编程好代码以及熟练掌握Turtle函数库 一.  相关代码如下: import turtle class St ...

  3. [转]找到MySQL发生swap的原因

    背景: 最近遇到了一个郁闷的问题:明明OS还有大量的空闲内存,可是却发生了SWAP,百思不得其解.先看下SWAP是干嘛的,了解下它的背景知识.在Linux下,SWAP的作用类似Windows系统下的“ ...

  4. Linux关于文件,文件夹操作命令

    文件 文件夹 相关操作命令 查看文件 cd 切换目录位置 ls 目录    查看指定目录所有文件  --缺省当前目录 ls -l 目录 查看指定目录所有文件的详细信息 --同 ll 命令 ls -a ...

  5. 反编译看java for-each循环

    java 1.5发行版引入的for-each循环.(引自<Effective Java>中文版第二版 第46条) 如以下对数组列表的for-each循环示例: public class F ...

  6. input type='file'文件上传自定义样式

    使用场景: 在未使用UI库时免不了会用到各种上传文件,那么默认的上传文件样式无法达到项目的要求,因此重写(修改)上传文件样式是必然的,下面的效果是最近项目中自己写的一个效果,写出来做个记录方便以后使用 ...

  7. IntelliJ IDEA 和谐地址及快捷键

    转载:http://my.oschina.NET/dyyweb/blog/494504 http://blog.csdn.net/tanlon_0308/article/details/5085473 ...

  8. spark wordcount 编程模型详解

    spark wordcount中一共经历多少个RDD?以及RDD提供的toDebugString    在控制台输入spark-shell   系统会默认创建一个SparkContext   sc h ...

  9. 包建强的培训课程(13):iOS与ReactNative

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  10. 通过脚本下载GO被墙或常用的相关包

    脚本描述 脚本依赖环境:Windows,GO,GIT 脚本将创建 temp 目录,并拷贝相关包到第一个 GOPATH 中 可将脚本保存到本地自行添加被墙或者常用的包 完整脚本代码 @echo off ...