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

    这个就是动态创建了. 

  • 相关阅读:
    June. 26th 2018, Week 26th. Tuesday
    June. 25th 2018, Week 26th. Monday
    June. 24th 2018, Week 26th. Sunday
    June. 23rd 2018, Week 25th. Saturday
    June. 22 2018, Week 25th. Friday
    June. 21 2018, Week 25th. Thursday
    June. 20 2018, Week 25th. Wednesday
    【2018.10.11 C与C++基础】C Preprocessor的功能及缺陷(草稿)
    June.19 2018, Week 25th Tuesday
    June 18. 2018, Week 25th. Monday
  • 原文地址:https://www.cnblogs.com/iBinary/p/9636144.html
Copyright © 2011-2022 走看看