zoukankan      html  css  js  c++  java
  • 宏定义中#和##及DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC宏

    #

    告诉编译器,将它后面字符串进行stringfication;

    ##

    告诉编译器,将两个字符串系在一起组成一个新的字符串;

    看了这个就理解了:

    #define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 
        static char _lpsz##class_name[] = #class_name;  // static char _lpszCView[] = "CView";
      ...

    注:这是宏定义中,编译器的行为。

    顺便,以最近的一个项目代码为例解释一下DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC宏

    • LiInspectorDlg.h
    class CLiInspectorDlg:public CDialog{
        DECLARE_DYNAMIC(CLiInspectorDlg)  // 1.
    public:
        ...
    };
    • LiInspectorDlg.cpp
    #include "LiInspectorDlg.h"
    ...
    
    IMPLEMENT_DYNAMIC(CLiInspectorDlg, CDialog)  // 2.
    ...
    ...
    

    先看头文件:

    把DECLARE_DYNAMIC(CLiInspectorDlg)宏声明展开为:

    class CLiInspectorDlg:public CDialog{
    public:
        static CRuntimeClass classCLiInspectorDlg; 
        virtual CRuntimeClass* GetRuntimeClass() const;
    public:
        ...
    };
    

    接着看源文件:

    把IMPLEMENT_DYNAMIC(CLiInspectorDlg, CDialog)宏声明展开为:

    static char _lpszCLiInspectorDlg[] = "CLiInspectorDlg";
    CRuntimeClass CLiInspectorDlg::classCLiInspectorDlg = { 
        _lpszCLiInspectorDlg, sizeof(CLiInspectorDlg), 0xFFFF, NULL, 
        &CDialog::classCDialog, NULL };
    static AFX_CLASSINIT _init_CLiInspectorDlg(&CLiInspectorDlg::classCLiInspectorDlg);
    CRuntimeClass* CLiInspectorDlg::classCLiInspectorDlg() const { 
        return &CLiInspectorDlg::classCLiInspectorDlg; }
    

    另外,AFX_CLASSINIT是一个struct,它负责类别型录网的link工作。。。它有一个构造函数为:

    // declare
    struct AFX_CLASSINIT{
        AFX_CLASSINIT(CRuntimeClass* pNewClass); 
    };
    // implement
    AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pNewClass){ 
        pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;
        CRuntimeClass::pFirstClass = pNewClass;
    }
    

      

     


     

    写给自己:

    SimRTTI的仿真代码

    个人总结:

    • 全局变量的内存分配,先于main;
    • new运算符,引发construction函数;
    • 类别型录网由simple list建立,它的顺序取决于IMPLEMENT_DYNAMIC(class_name, base_class_name)的顺序,class_name决定了list的节点元素;
    • sizeof空类也会占用4byte的,不然还不用内存呀,哼想的美。。。。相关知识看其它笔记吧;
    • new引发的construction函数,如果没有delete与之对应,在vs2013编译器中未追踪到destruction函数;

    只看到这些destruction函数的运行,他们是对应于全局变量的;那么,new对应的呢?没找到。。

    附上construction函数的运行;

     

    注:可查看代码的不同版本来追溯回忆当时的思路

     


     

    IsKindOf功能仿真:

    • 添加了IsKindOf接口函数,由于错误定义了_IMPLEMENT_RUNTIMECLASS造成IsKindOf函数死循环;
    • 另外,添加的new和delete来观察construction函数和destruction函数的动作;

    个人总结:

    • IsKindOf功能的实现,依赖于base_class_name;类别型录的建立连接,依赖于AFX_CLASSINIT和class_name;
    • static相关(看其它笔记):宏定义中的static变量和函数的实现,只有初始化时执行一次;局部static和全局static的区别;
    • new,如果有delete对应,会引发destruction;如果没有,程序退出时触发destruction;
    • 注意IMPLEMENT_DYNAMIC的触发时间;

    最后,注意一下这几个函数的位置:Create()、CreateEx()、Run()、PreCreateWindow()、InitInstance()、InitApplication();以及m_pMainWnd和m_pCurrentWinApp。

  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/xiawuhao2013/p/10083639.html
Copyright © 2011-2022 走看看