首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MFC原理第四讲.动态创建机制

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

作者头像
IBinary
发布2019-05-25 16:47:20
1K0
发布2019-05-25 16:47:20
举报
文章被收录于专栏:逆向技术逆向技术

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

这个就是动态创建了.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •               MFC原理第四讲.动态创建机制
    • 一丶要学习的知识点以及简介
      • 二丶如何使用动态创建.
        • 三丶动态创建实现原理 之 宏 拆开
          • 1. DECLARE_DYNCREATE 宏拆开
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档