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

    这个就是动态创建了. 

  • 相关阅读:
    函数(一.return)
    if、for、while的详解及实例(一)
    Silverlight 中 TreeView 的数据绑定
    跟着微软玩 WCF RIA Services (1) – 安装AdventureWorks OLTP数据库
    MEF学习(一) MEF介绍
    WCF学习笔记(1)面向服务
    基础知识应用程序配置文件(将section转换成对象一)
    Silverlight编译出错: 未给任务“CreateRiaClientFilesTask”的必需参数“ClientFrameworkPath”赋值
    悟道MVVM 一 各施其职
    Lync 2010 二次开发(一) 开发环境的部署
  • 原文地址:https://www.cnblogs.com/iBinary/p/9636144.html
Copyright © 2011-2022 走看看