友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

深入浅出MFC第2版(PDF格式)-第23部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!



                                                     第3章    MFC 六大關鍵技術之模擬 



DECLARE_DYNAMIC  / IMPLEMENT_DYNAMIC 宏 



     为了神不知鬼不觉把CRuntimeClass 对象塞到类别之中,并声明一个可以抓到该对象地 



     址的函数,我们定义DECLARE_DYNAMIC 宏如下: 



         #define DECLARE_DYNAMIC (class_name)  

         public:  

                 static CRuntimeClass class##class_name;  

                 virtual CRuntimeClass* GetRuntimeClass() const; 



      出现在宏定义之中的## ,用来告诉编译器,把两个字符串系在一起。如果你这么使用此 



      宏: 



         DECLARE_DYNAMIC(CView) 



       编译器前置处理器为你做出的码是: 



         public: 

                 static CRuntimeClass classCView; 

                 virtual CRuntimeClass* GetRuntimeClass() const; 



       这下子,只要在声明类别时放入DECLARE_DYNAMIC 宏即万事OK 喽。 



       不,还没有OK ,类别型录(也就是各个CRuntimeClass 对象)的内容指定以及串接工 



       作最好也能够神不知鬼不觉,我们于是再定义IMPLEMENT_DYNAMIC 宏: 



         #define IMPLEMENT_DYNAMIC (class_name; base_class_name)  

                 _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; 0xFFFF; NULL) 



       其中的_IMPLEMENT_RUNTIMECLASS 又是一个宏。这样区分是为了此一宏在「动 



       态生成」(下一节主题)时还会用到。 



     #define _IMPLEMENT_RUNTIMECLASS (class_name; base_class_name;wSchema;pfnNew)  

             static char _lpsz##class_name'' = #class_name;  

             CRuntimeClass class_name::class##class_name = {  

                     _lpsz##class_name; sizeof(class_name); wSchema; pfnNew;  

                             RUNTIME_CLASS (base_class_name); NULL };  

             static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);  

             CRuntimeClass* class_name::GetRuntimeClass() const  

                     { return &class_name::class##class_name; }  



                                                                                      125 


…………………………………………………………Page 188……………………………………………………………

                   第篇  勿在浮砂築高台 



                    其中又有RUNTIME_CLASS 宏,定义如下: 

                       #define RUNTIME_CLASS (class_name)  

                               (&class_name::class##class_name) 



                    看起来整个IMPLEMENT_DYNAMIC  内容好象只是指定初值,不然,其曼妙处在于它所 



                    使用的一个struct AFX_CLASSINIT ,定义如下: 



                       struct AFX_CLASSINIT 

                               { AFX_CLASSINIT(CRuntimeClass* pNewClass); }; 



                    这表示它有一个构造式(别惊讶,C++  的struct 与class 都有构造式),定义如下: 



                       AFX_CLASSINIT::AFX_CLASSINIT (CRuntimeClass* pNewClass) 

                        { 

                               pNewClass…》m_pNextClass = CRuntimeClass::pFirstClass; 

                               CRuntimeClass::pFirstClass = pNewClass; 

                        } 



                     很明显,此构造式负责linked list 的串接工作。 



                     整组宏看起来有点吓人,其实也没有什么,文字代换而已。现在看看这个实例: 



                       // in header file 

                       class CView : public CWnd 

                        { 

                               DECLARE_DYNAMIC(CView) 

                               。。。 

                        }; 



                       // in implementation file 

                       IMPLEMENT_DYNAMIC(CView; CWnd) 



                      上述的码展开来成为: 



                       // in header file 

                       class CView : public CWnd 

                        { 

                       public: 

                               static CRuntimeClass classCView;  

                               virtual CRuntimeClass* GetRuntimeClass() const; 

                               。。。 

                        }; 



126 


…………………………………………………………Page 189……………………………………………………………

     // in implementation file 

     static char _lpszCView'' = 〃CView〃; 

     CRuntimeClass CView::classCView = { 

             _lpszCView; sizeof(CView); 0xFFFF; NULL; 

                     &CWnd::classCWnd; NULL }; 

     static AFX_CLASSINIT _init_CView (&CView::classCView); 

     CRuntimeClass* CView::GetRuntimeClass() const 

             { return &CView::classCView; } 



  于是乎, 程序中只需要简简单单的两个宏DECLARE_DYNAMIC(Cxxx) 和 



  IMPLEMENT_DYNAMIC(Cxxx; Cxxxbase)  ,就完成了构造资料并加入串行的工作: 



                              Cxxx ::classCxxx 



                                   “Cxxx” 



                                 sizeof(Cxxx) 



                                   0xFFFF 



                             m_pfnCreateObject       NULL 



                               m_pBaseClass          Cxxxbase::classCxxxbase 



                                m_pNextClass 



可是你知道,串行的头,总是需要特别费心处理,不能够套用一般的串行行为模式。我 



们的类别根源CObject , 不能套用现成的宏DECLARE_DYNAMIC 和 



IMPLEMENT_DYNAMIC ,必须特别设计如下: 



 // in header file 

 class CObject 

  { 

 public: 

   virtual CRuntimeClass* GetRuntimeClass() const; 

   。。。 

 public: 

   static CRuntimeClass classCObject; 

  }; 



                                                                                            127 


…………………………………………………………Page 190……………………………………………………………

                    第篇  勿在浮砂築高台 



                    // in implementation file 

                    static char szCObject'' = 〃CObject〃; 

                    struct CRuntimeClass CObject::classCObject = 

                            { szCObject; sizeof(CObject); 0xffff; NULL; NULL }; 

                    static AFX_CLASSINIT _init_CObject (&CObject::classCObject); 



                    CRuntimeClass* CObject::GetRuntimeClass() const 

                     { 

                            return &CObject::classCObject; 

                     } 



                   并且,CRuntimeClass 中的static 成员变量应该要初始化(如果你忘记了,赶快复习第 



                    2章的「静态成员(变量与函数)」一节): 



                    // in implementation file 

                    CRuntimeClass* CRuntimeClass::pFirstClass = NULL; 



                     终于,整个「类别型录」串行的头部就这样形成了: 



                                                         CObject::classCObject 



                                                               “CObject” 



                                                            sizeof(CObject) 



                           CRuntimeClass::pFirstClass           0xFFFF 



                             (static  

                                  变量)                      m_pfnCreateObject       NULL 



                                                             m_pBaseClass          NULL 



                                                             m_pNextClass 



                                                                                           NULL 



128 


…………………………………………………………Page 191……………………………………………………………

                                                      第3章    MFC 六大關鍵技術之模擬 



范例程序Frame3 在。h 档中有这些类别声明: 



 CObject 

  CObject 



     CCmdTarget 

     CCmdTarget 



        CWinThread 

         CWinThread 



            CWinApp 

             CWinApp 



                CMyWinApp 

                CMyWinApp 



        CWnd 

         CWnd 



            CView 



                CMyView 

                CMyView 



            CFrameWnd 

             CFrameWnd 



                CMyFrameWnd 

                CMyFrameWnd 



        CDocument 

         CDocument 



            CMyDoc 

             CMyDoc 



class CObject 

{ 

。。。 

}; 

class CCmdTarget : public CObject 

{ 

      DECLARE_DYNAMIC(CCmdTarget) 

。。。 

}; 

class CWinThread : public CCmdTarget 

{ 

      DECLARE_DYNAMIC(CWinThread) 

。。。 

}; 

class CWinApp : public CWinThread 

{ 

      DECLARE_DYNAMIC(CWinApp) 

。。。 

}; 

class CDocument : public CCmdTarget 

{ 

      DECLARE_DYNAMIC(CDocument) 



                                                                                           129 


…………………………………………………………Page 192……………………………………………………………

                  第篇  勿在浮砂築高台 



                  。。。 

                  }; 

                  class CWnd : public CCmdTarget 

                  { 

                        DECLARE_DYNAMIC(CWnd)   

                                               // 其实在MFC 中是DECLARE_DYNCREATE(),见下节。 

                  。。。 

                  }; 

                  class CFrameWnd : public CWnd 

                  { 

                                                  // 其实在MFC 中是DECLARE_DYNCREATE(),见下节。 

                       DECLARE_DYNAMIC(CFrameWnd)  

                  。。。 

                  }; 

                  class CView : public CWnd 

                  { 

                        DECLARE_DYNAMIC(CView) 

                  。。。 

                  }; 

                  class CMyWinApp : public CWinApp 

                  { 

                  。。。 

                  }; 

                  class CMyFrameWnd : public CFrameWnd 

                  { 

                    。。。 // 其实在MFC 应用程序中这里也有DECLARE_DYNCREATE(),见下节。 

                  }; 

                  class CMyDoc : public CDocument 

                  { 

                    。。。 // 其实在MFC 应用程序中这里也有DECLARE_DYNCREATE(),见下节。 

                  }; 

                  class CMyView : public CView 

                  { 

                    。。。 // 其实在MFC 应用程序中这里也有DECLARE_DYNCREATE(),见下节。 

                  }; 



                  范例程序Frame3 在。cpp 档中有这些动作: 



                  IMPLEMENT_DYNAMIC(CCmdTarget; CObject) 



                  IMPLEMENT_DYNAMIC(CWinThread; CCmdTarget) 



                  IMPLEMENT_DYNAMIC(CWinApp; CWinThread) 



                  IMPLEMENT_DYNAMIC(CWnd; CCmdTarget) // 其实在MFC 中它是IMPLEMENT_DYNCREATE(),见下节。 



                  IMPLEMENT_DYNAMIC(CFrameWnd; CWnd) // 其实在MFC 中它是IMPLEMENT_DYNCREATE(),见下节。 



                  IMPLEMENT_DYNAMIC(CDocument; CCmdTarget) 



                  IMPLEMENT_DYNAMIC(CView; CWnd) 



                  于是组织出图3…1 这样一个大网。 



130 


…………………………………………………………Page 193……………………………………………………………

                                                            第3章    MFC 六大關鍵技術之模擬 



       CObject::classCObject    CCmdTarget::classCCmdTarget      CWinThread::classCWinThread 



            “CObject”                    “CCmdTarget”                  “CWinThread” 



          m_pBaseClass                   m_pBaseClass                  m_pBaseClass 

          m_pNextClass                   m_pNextClass                  m_pNextClass 



                         NULL 

   NULL 



     CFrameWnd::classCFrameWnd        CWnd::classCWnd              CWinApp::classCWinApp 



          “CFrameWnd”                       “CWnd”                       “CWinApp” 



          m_pBaseClass                   m_pBaseClass                  m_pBaseClass 

          m_pNextClass                   m_pNextClass                  m_pNextClass 



       CDocument::classCDocument      CView::classCView 



           “CDocument”                     “CView” 



                                                                     (static 变量) 



                                                                     CRuntimeClass::pFirstClass 



          m_pBaseClass                   m_pBaseClass 

          m_pNextClass                   m_pNextClass 



    图3…1 CRuntimeClass 对象构成的类别型录网。本图只列出与RTTI 有关系 



           的成员。 



为了实证整个类别型录网的存在,我在main  函数中调用PrintAllClasses ,把串行中的每 



一个元素的类别名称、对象大小、以及schema no。 印出来: 



  void PrintAllClasses() 

  { 

      CRuntimeClass* pClass; 



      // just walk through the simple list of registered classes 

      for (pClass = CRuntimeClass::pFirstClass; pClass != NULL; 

              pClass = pClass…》m_pNextClass) 

      { 

          cout m_lpszClassName 
返回目录 上一页 下一页 回到顶部 9 10
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!