专栏首页逆向技术MFC原理第四讲.动态创建机制

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

              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里面添加自己创建对象的函数指针. 然后自己的类中实现这个函数.创建自己的对象并且返回

这个就是动态创建了.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 程序员如何提高技术层次

    你想进什么公司,和你读什么计算机方向,关系不是很大。只要是理工科的学生,面对技术岗位,其实机会是差不多的。

    奋斗蒙
  • 虽然Python超越了java,可是java的江湖地位还是无人可撼动是吗?

    没有听过python这门编程语言已经超越java,现在只不过现在的势头很猛,特别是借助人工智能的大趋势,再加上培训机构的推波助澜好像一夜之间成为第一编程语言,但...

    程序员互动联盟
  • java 多态 向上转型 后期绑定一例

    switch中的 default 语句不管放在哪个位置,都是在所有case都不满足的情况下最后执行。 foreach语句 for(元素类型 元素变量;遍历...

    葫芦
  • Windows 10是用什么语言写的?微软工程师带你“偷窥”源码

    导读:Windows 操作系统本身是不开源的,但是近日微软内核工程师 Axel Rietschin 发表了一篇博客,带大家一窥 Windows 10 内核的魅力...

    华章科技
  • Random在高并发下的缺陷以及JUC对其的优化

    Random可以说是每个开发都知道,而且都用的很6的类,如果你说,你没有用过Random,也不知道Random是什么鬼,那么你也不会来到这个技术类型的社区,也看...

    java架构师
  • 详解Nginx location 匹配规则

    本篇文章主要介绍了Nginx location 匹配规则,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    习惯说一说
  • JavaScript 程序员可以从C ++中学到什么[每日前端夜话0x60]

    时间的结束?图片来自 Jens Kreuter 由Bret Cameron修改。

    疯狂的技术宅
  • 为什么一些优秀的java框架都是外国人写的,为什么国内的程序员大部分只会搬砖?

    作为一个写了十几年代码的程序员,平时用的比较多的有三种编程语言,C/C++ java,相对来讲C/C++爱的更加深刻一点,国内普遍一个现象拿到的源码基本上都是国...

    程序员互动联盟
  • c++ 开发中利用yaml-cpp读写yaml配置文件

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/briblue/article/details/895...

    Frank909
  • 传统企业c++程序员想转互联网企业,项目经验不对应,转的过去吗?

    从就业形势上看现在互联网的薪资相对高一些,对于编程语言来讲不会区分是不是传统企业还是互联网企业,C++属于资深类型的编程语言需要经历过几年的项目磨炼,国内的互联...

    程序员互动联盟

扫码关注云+社区

领取腾讯云代金券