友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第42章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






                                                                              m_wSchema 



                          CRuntimeClass::pFirstClass                       m_pfnCreateObject 

                           (static 变量) 

                                                                             m_pBaseClass 



                                                                             m_pNextClass 



                        我希望,每一个类别都能拥有这样一个CRuntimeClass 成员变量,并且最好有一定的命名 



                        规则(例如在类别名称之前冠以〃class〃 作为它的名称),然后,经由某种手段将整个 



                        类别库构造好之后,「类别型录」能呈现类似这样的风貌: 



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



                               “CObject”                    “CCmdTarget”                  “CWinThread” 



                             m_pBaseClass                  m_pBaseClass                   m_pBaseClass 

                             m_pNextClass                   m_pNextClass                  m_pNextClass 



                      NULL                  NULL               CObject::classCObject CCmdTarget::classCCmdTarget 



                                                         CWnd::classCWnd             CWinApp::classCWinApp 



                                                              “CWnd”                        “CWinApp” 



                       static 变量 



                       CRuntimeClass::pFirstClass 



                                                           m_pBaseClass                   m_pBaseClass 



                                                            m_pNextClass                  m_pNextClass 



                                                        CCmdTarget::classCCmdTarget  CWinThread::classCWinThread 



124 


…………………………………………………………Page 187……………………………………………………………

                                                     第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 

                     { 

                   
返回目录 上一页 下一页 回到顶部 0 1
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!