深入浅出MFC学习笔记:(第三章MFC六大关键技术之仿真:类型识别,动态创建) .

第三章MFC六大关键技术之仿真:类型识别

   深入理解MFC的内部运行原理,是本次学习《深入浅出MFC》的主要目的。要模仿的六大技术包括:

1:MFC程序的初始化过程。

2:RTTIRuntime type identification)运行时类型识别。

3:Dynamic creation 动态创建

4:Persistence永久保存

5:消息映射

6:消息传递。

RTTI(运行时类型识别)

    IsKindOf能够侦测某个对象是否属于某种类。即判断某一对象所属的类是否是父类或当前类;

    要达到动态类型识别的能力,必须在构建类继承体系时记录必要的信息,这被称为类型型录表。MFC以链表的方式建立了此表。

    类型型录表的每个元素为CRuntimeClass类型,其定义为:

[cpp]  view plain copy
  1. class CRuntimeClass  
  2.   
  3. {  
  4.   
  5. public:  
  6.   
  7.    LPCSTR m_lpszClassName;//对象所属类名  
  8.   
  9.    Int m_nObjectSize;//对象大小  
  10.   
  11.    UINT m_wSchema;//模式号  
  12.   
  13.    CObject *(PASCAL*m_pfnCreateObject)();//构建函数抽象类为NULL  
  14.   
  15.    CRuntimeClass *pBaseClasss;//基类CRuntimeClass对象指针。  
  16.   
  17.    Static CRuntimeClass *pFirstClass;//链表头指针。  
  18.   
  19.    CRuntimeClass  *m_pNextClass;//下一指针。  
  20.   
  21. };  


 

MFC使用此类作为每个类的成员变量。使用宏定义为每个类定义了自己的CRuntimeClass成员变量。

DECLAR_DYNAMIC和IMPLENMENT_DYNAMIC

使用这两个宏将CRuntimeClass对象不知不觉放到类之中。

DECLARE_DYNMIC宏定义如下:

[cpp]  view plain copy
  1. #define DELCARE_DYNMIC (  class_name   )   \  
  2.   
  3. public:\  
  4.   
  5.      static CRuntimeClass class##class_name  \  
  6.   
  7.      virtual CRuntimeClass *GetRuntimeClass()const;  


 

##用来告诉编译器把两个字符串连接起来。

如果使用这个宏:DELCARE_DYNMICCView);

那么预编译器将生成下列代码:

[cpp]  view plain copy
  1. public:  
  2.   
  3. static CRuntimeClass classCView;  
  4.   
  5. virtual CRuntimeClass*GetRuntimeClass()const;  



 

以上代码仅仅是在类中定义CRuntimeClass对象,并定义一个返回CRuntimeClass对象地址的函数。注意CRuntimeClassstatic的,也就是说同一种类继承体系的对象共享一个CRuntimeClass对象。

初始化对象的内容以及建立类型型录表需要使用IMPLEMENT_DYNMIC宏。

[cpp]  view plain copy
  1. #define IMPLEMENT_DYNMIC (class_name,base_class_name)\  
  2.   
  3. _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL);   
  4.   
  5. _IMPLEMENT_RUNTIMECLASS又是一个宏,它定义如下:  
  6.   
  7. #define _IMPLEMENT_RUNTIMECLASS(class_name,\  
  8.   
  9.     base_class_name,wSchema,pfnNew)\  
  10.   
  11.      static char _lpsz##class_name[]=#class_name;\  
  12.   
  13.      CRuntimeClass class_name::class##class_name=\  
  14.   
  15.        { _lpsz##class_name,sizeof(class_name),\  
  16.   
  17.          wSchema,pfnNew,\  
  18.   
  19.           RUNTIME_CLASS(base_class_name),NULL\  
  20.   
  21.         };  
  22.   
  23.       static AFX_CLASSINIT _init##class_name \  
  24.   
  25.       ( & class_name::class##class_name);\  
  26.   
  27.        CRuntimeClass *class_name::GetRuntimeClass()const\  
  28.   
  29.        {\  
  30.   
  31.           return &class_name::class##classname;\  
  32.   
  33.         }  
  34.   
  35. #define RUNTIME_CLASS(class_name)\  
  36.   
  37.    ( &class_name::class##class_name);  


 

AFX_CLASSINIT是一个类,看着跟宏定义似的,这样做很容易让人迷惑。它用于将本节点连接到类型型录表,定义如下:

[cpp]  view plain copy
  1. class AFX_CLASSINIT  
  2.   
  3. {  
  4.   
  5.   public:  
  6.   
  7.      AFX_CLASSINIT(CRuntimeClass*pNewClass)//构造函数  
  8.   
  9.      {   
  10.   
  11.        pNewClass->m_pNextClass=CRuntime::pFirstClass;  
  12.   
  13.        CRuntimeClass::pFirstClass =pNewClass;  
  14.   
  15.      }  
  16.   
  17. };  


 

用法:

[cpp]  view plain copy
  1. class CWnd:public CCmdTarget  
  2.   
  3. {  
  4.   
  5.   public:  
  6.   
  7.     DECLARE_DYNAMIC(CWnd);  
  8.   
  9.   
  10. };  


 

IMPLEMENT_DYNMIC(CWnd,CCmdTarget);

代码展开后为;

[cpp]  view plain copy
  1. class CWnd:public CCmdTarget  
  2.   
  3. {  
  4.   
  5.   public:  
  6.   
  7.     static CRuntimeClass classCView;  
  8.   
  9.     virtual CRuntimeClass*GetRuntimeClass()const  
  10.   
  11.        
  12.   
  13. };  
  14.   
  15.   
  16.   
  17. static char _lpszCWnd[]="CWnd";  
  18.   
  19. CRuntimeClass CWnd::classCWnd=  
  20.   
  21. {  
  22.   
  23. _lpszCView , sizeof(CWnd) , FFFF,NULL , &Wnd::classCWnd , NULL);  
  24.   
  25. };  
  26.   
  27. static AFX_CLASSINIT _init_CWnd(&CWnd::classCWnd);  
  28.   
  29. {  
  30.   
  31.    Return &CWnd::classCWnd;  
  32.   
  33. }  


 

定义宏的过程很复杂,但是一旦定义好之后,在使用时仅仅两句话就可以完成定义CRuntimeClass对象并且连接类型型录链表的工作。

CObject是所有类的基类,也是链表的头,此类应特别定义,不能在CObject内使用定义好的宏。

[cpp]  view plain copy
  1. class CObject  
  2.   
  3. {  
  4.   
  5.   public:  
  6.   
  7.      virtual CRuntimeClass*GetRuntimeClass()const;  
  8.   
  9.      static CRuntimeClass classCObject;  
  10.   
  11. };  
  12.   
  13. static char szCobject[]="CObject";  
  14.   
  15. struct CRuntimeClass CObject::classCObject=  
  16.   
  17. {  
  18.   
  19.   szCObject ,sizeof(CObject),0xFFFF,NULL,NULL,NULL  
  20.   
  21. };  
  22.   
  23. static AFX_CLASSINIT _init_CObject(&Cobject::classObject);  
  24.   
  25. CRuntimeClass *CObject::GetRuntimeClass()const  
  26.   
  27. {  
  28.   
  29.   return &CObject::classCObject;  
  30.   
  31. }  


 

由于CRuntimeClass对象是static成员变量,因此需要在类外初始化。如果忘记初始化将会报链接错误。

CRuntimeClass*CRuntimeClass::pFirstClass=NULL;

建好了类类型路表,要实现IsKindOf功能很容易。首先在CObject加上一个IsKindOf函数,于是所有继承自此类的类都具有类型识别的功能。能够将某个CRuntimeClass对象与类类型型录中的元素进行比较。如:

 

[cpp]  view plain copy
  1.    class CObject  
  2.   
  3. {  
  4.   
  5.    public:  
  6.   
  7. bool IsKindOf(const CRuntimeClass*pClass)const  
  8.   
  9. {  
  10.   
  11.   CRuntimeClass *pClassThis=GetRuntimeClass();  
  12.   
  13.    while(pClassThis)  
  14.   
  15.    {  
  16.   
  17.      if(pClassThis==pClass)  
  18.   
  19.        return true;  
  20.   
  21.      pClassThis=pClassThis->m_pBaseClass;//沿着基类寻找。  
  22.   
  23.    }  
  24.   
  25.    return false;  
  26.   
  27. }  
  28.   
  29. };  


 


如果我们调用CWnd *cw=new CWnd;

    cw->IsKindOf(RUNTIME_CLASS(CFrameWnd));

    RUNTIME_CLASS实际就是&CFrameWnd::classCFrameWnd,它就是CFrameWndstaticCRuntimeClass类型成员。函数内利用GetRuntimeClass取得本类的CRuntimeClass对象的地址,即&CWnd::classCWnd,然后进行比较。因为每一类型共用一个staticCRuntimeClass对象,因此属于同于类的CRuntimeClass对象的地址相同。

动态创建

    每一类的构建函数可以记录在类型别录中,当获得一个类名称,通过查找类别型录表找出对应的元素,然后调用其构建函数产生新对象。

    在CRuntimeClassm_pfnCreateObject即为构建函数首地址。

为了实现动态创建,需要添加两个宏:

DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE

如:

[cpp]  view plain copy
  1. #define DECLARE_DYNCREATE(class_name)\  
  2.   
  3.     DECLARE_DYNCREATE(class_name)\  
  4.   
  5. static CObject *PASCAL CreateObject();  
  6.   
  7. #define IMPLEMENT_DYNCREATE (class_name,base_class_name)\  
  8.   
  9.    CObject*PASCAL class_name::CreateObject()\  
  10.   
  11.    {return new classname;};\  
  12.   
  13.     _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,  
  14.   
  15.     0xFFFF,class_name::CreateObject)  


 

CFrameWnd为例,下列程序代码:

[cpp]  view plain copy
  1. class CFrameWnd:public CWnd  
  2.   
  3. {  
  4.   
  5.    public:  
  6.   
  7.     DECLEARE_DYNCREATE(CFrameWnd);  
  8.   
  9. };  


 

IMPLEMENT_DYNCREATE(CFrameWnd,CWnd);

展开如下:

 

[cpp]  view plain copy
  1. class CFrame:public CWnd  
  2.   
  3. {  
  4.   
  5.   public:  
  6.   
  7.    static CRuntimeClass classCFrameWnd;  
  8.   
  9.    virtual CRuntimeClass *GetRuntimeClass()const;  
  10.   
  11.    static CObject *PASCAL CreateObject();  
  12.   
  13. };  
  14.   
  15. CObject _PASCAL CFrameWnd::CreateObject()  
  16.   
  17. {  
  18.   
  19. return new CFrameWnd;  
  20. }  
  21.   
  22. static char _lpszCFrameWnd[]="CFrameWnd";  
  23.   
  24. CRuntimeClass CFrameClass::classCFrameWnd={  
  25.   
  26.  _lpszCFrameWnd,sizeof(CFrameWnd),0xFFFF,CFrameWnd::CreateObject,RUNTIME_CALSS(CWnd),NULL};  
  27.   
  28. static AFX_CLASSINIT _init_CFrameWnd  
  29.   
  30.                       (&CFrameWnd::classCFrameWnd);  
  31.   
  32. CRuntimeClass*CFrameWnd::GetRunimeClass()const  
  33.   
  34. {return &CFrameWnd::classCFrameWnd;}  


 

注意对象构建函数为static函数。

为了支持动态创建需要在CRuntimeClass内添加两个函数:CreateObjectCRuntimeClass::Load成员函数。

[cpp]  view plain copy
  1. CObject *CRuntimeClass::CreateObject()  
  2.   
  3. {  
  4.   
  5.    If(m_pfnCreateObject==NULL)//不支持动态创建。  
  6.   
  7.     {  
  8.   
  9.         throw runtime_error("此类不支持动态创建");  
  10.   
  11.         Return NULL;  
  12.   
  13.     }  
  14.   
  15.     CObject*pObject=(*m_pfnCreateObject)();  
  16.   
  17.     Return pObject;  
  18.   
  19. }  
  20.   
  21. CRuntimeClass*PASCL CRuntimeClass::Load()  
  22.   
  23. {  
  24.   
  25.    Char szClassName[64];  
  26.   
  27.    CRuntimeClass*pClass  
  28.   
  29.   cout<<"输入一个类名:";  
  30.   
  31.   cin>>szClassName;  
  32.   
  33.    for(pClass=pFirstClass;pClass;pClass=pClass->m_pNextClass)  
  34.   
  35.     {  
  36.   
  37.        if(strcmp(szClassName,pClass->m_lpszClassName)==0)  
  38.   
  39.                return pClass;  
  40.   
  41.         return NULL;  
  42.   
  43.     }  
  44.   
  45. }  


 

以下为类型识别及动态创建的完整代码:

[cpp]  view plain copy
  1. <span style="font-size:18px;">#include<iostream>  
  2. #include<windows.h>  
  3. #include<string>  
  4. using namespace std;  
  5.   
  6. class CObject;  
  7. class CRuntimeClass  
  8. {  
  9. public:  
  10.     char* m_lpszClassName;//对象所属类名  
  11.     int m_nObjectSize;//对象大小  
  12.     int m_wSchema;//模式号  
  13.     CObject*(PASCAL*m_pfnCreateObject)();//构建函数,抽象类为NULL  
  14.     CRuntimeClass *m_pBaseClasss;//基类CRuntimeClass对象指针。  
  15.     static CRuntimeClass *pFirstClass;//链表头指针。static  
  16.     CRuntimeClass  *m_pNextClass;//下一指针。  
  17. public:  
  18.     CObject*CreateObject()  
  19.     {  
  20.         if(m_pfnCreateObject==NULL)  
  21.         {  
  22.             cout<<"该类型不支持动态创建!!"<<endl;  
  23.             return NULL;  
  24.         }  
  25.         CObject*pClass=(*m_pfnCreateObject)();  
  26.         return pClass;  
  27.     }  
  28.     static CRuntimeClass*Load()  
  29.     {  
  30.         cout<<"请输入要动态创建的类名:";  
  31.         string s;  
  32.         cin>>s;  
  33.         for(CRuntimeClass*pClass=pFirstClass;pClass;pClass=pClass->m_pBaseClasss)  
  34.         {  
  35.             if(pClass->m_lpszClassName==s)  
  36.             {  
  37.                 return pClass;  
  38.             }  
  39.         }  
  40.         return NULL;  
  41.     }  
  42. };  
  43.   
  44. class AFX_CLASSINIT  
  45. {  
  46. public:  
  47.     AFX_CLASSINIT(CRuntimeClass*pNewClass)//构造函数  
  48.       {   
  49.          pNewClass->m_pNextClass=CRuntimeClass::pFirstClass;  
  50.         CRuntimeClass::pFirstClass =pNewClass;  
  51.       }  
  52.  };  
  53.   
  54. /************************************************************************/  
  55. /* 动态类型识别宏定义                 
  56. //与CRuntimeClass类中的构建函数相区别。此处的CreateObject函数在每个类中都以static成员函数存在,用以 
  57. //初始化类型型录表,而CRuntimeClass中的CreateObject用于调用每个类的构建函数。仅仅是函数名相同罢了。*/  
  58. /************************************************************************/  
  59.   
  60. #define DECLARE_DYNAMIC(class_name)\  
  61.      public:\  
  62.            static CRuntimeClass Class##class_name;\  
  63.            virtual CRuntimeClass*GetRuntimeClass()const;\  
  64.   
  65.   
  66. #define DECLARE_DYNCREATE(class_name)\  
  67.        DECLARE_DYNAMIC(class_name)\  
  68.        static CObject*PASCAL CreateObject();\  
  69.   
  70. #define RUNTIME_CLASS(class_name)\  
  71.     (&class_name::Class##class_name)\  
  72.   
  73. #define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)\  
  74.     class CRuntimeClass class_name::Class##class_name ={\  
  75.     #class_name,\  
  76.     sizeof(class_name),wSchema,pfnNew,RUNTIME_CLASS(base_class_name),NULL};\  
  77.     static AFX_CLASSINIT _init##class_name( RUNTIME_CLASS(class_name));\  
  78.     CRuntimeClass *class_name::GetRuntimeClass()const\  
  79.     {return &class_name::Class##class_name;}//此处将class_name写成了classname花了一两天才查出来。啊啊啊啊啊。20120605  
  80.   
  81.   
  82. #define IMPLEMENT_DYNAMIC(class_name,base_class_name)\  
  83.     _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)\  
  84.   
  85. #define IMPLEMENT_DYNCREATE(class_name,base_class_name)\  
  86.     CObject*PASCAL class_name::CreateObject(){return new class_name;}\  
  87.     _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name::CreateObject)\  
  88.   
  89.   
  90. /************************************************************************/  
  91. /*  对CObject特殊处理。                                                   */  
  92. /************************************************************************/  
  93. class CObject  
  94. {  
  95. public:  
  96.     CObject()  
  97.     {  
  98.         //cout<<"CObject constructor!"<<endl;  
  99.     }  
  100.     ~CObject()  
  101.     {  
  102.         //cout<<"CObject destructor!"<<endl;  
  103.     }  
  104. public:  
  105.     virtual CRuntimeClass*GetRuntimeClass();  
  106.     static CRuntimeClass  ClassCObject;  
  107. public:  
  108.     bool IsKindOf(CRuntimeClass*pClass)  
  109.     {  
  110.         CRuntimeClass *pThis=GetRuntimeClass();  
  111.         for(;pThis;pThis=pThis->m_pBaseClasss)  
  112.         {  
  113.             if(pThis==pClass)  
  114.             {  
  115.                 return true;  
  116.             }  
  117.         }  
  118.         return false;  
  119.     }  
  120. };  
  121. class CRuntimeClass CObject:: ClassCObject=  
  122. {  
  123.    "CObject",sizeof(CObject),0xFFFF,NULL,NULL,NULL  
  124. };  
  125. static AFX_CLASSINIT _init_CObject(&CObject:: ClassCObject);  
  126. CRuntimeClass *CObject::GetRuntimeClass()  
  127. {  
  128.     return &CObject::ClassCObject;  
  129. }  
  130. CRuntimeClass*CRuntimeClass::pFirstClass=NULL;  
  131.   
  132. /************************************************************************/  
  133. /*                                                                      */  
  134. /************************************************************************/  
  135. class CCmdTarget:public CObject  
  136. {  
  137.     DECLARE_DYNCREATE(CCmdTarget)  
  138. public:  
  139.     CCmdTarget()  
  140.     {  
  141.         //cout<<"CCmdTarget constructor!"<<endl;  
  142.         //CreateObject();  
  143.     }  
  144.     ~CCmdTarget()  
  145.     {  
  146.         //cout<<"CCmdTarget destructor!"<<endl;  
  147.     }     
  148.   
  149. };  
  150. IMPLEMENT_DYNCREATE(CCmdTarget,CObject)  
  151.   
  152.   
  153.         ;  
  154. class CWnd:public CCmdTarget  
  155. {  
  156.     DECLARE_DYNCREATE(CWnd)  
  157. public:  
  158.     CWnd()  
  159.     {  
  160.         //cout<<"CWnd constructor"<<endl;  
  161.     }  
  162.     ~CWnd()  
  163.     {  
  164.         //cout<<"CWnd destructor"<<endl;  
  165.     }  
  166. public:  
  167.     virtual bool Create()  
  168.     {  
  169.         cout<<"CWnd::Create"<<endl;  
  170.         CreateEx();  
  171.         return true;  
  172.     }  
  173.     bool CreateEx()  
  174.     {  
  175.         cout<<"CWnd::CreateEx"<<endl;  
  176.         PreCreateWindow();  
  177.         return true;  
  178.     }  
  179.     virtual bool PreCreateWindow()  
  180.     {  
  181.         cout<<"CWnd::PreCreateWindow"<<endl;  
  182.         return true;  
  183.     }  
  184. };  
  185. IMPLEMENT_DYNCREATE(CWnd,CCmdTarget)  
  186.   
  187. class CView :public CWnd  
  188. {  
  189.     DECLARE_DYNCREATE(CView)  
  190. public:  
  191.     CView()  
  192.     {  
  193.         //cout<<"CView constructor"<<endl;  
  194.   
  195.     }  
  196.     ~CView()  
  197.     {  
  198.         //cout<<"CView destructor"<<endl;  
  199.     }  
  200.   
  201. };  
  202. IMPLEMENT_DYNCREATE(CView,CWnd)  
  203.   
  204. class CFrameWnd:public CWnd  
  205. {  
  206.     DECLARE_DYNCREATE(CFrameWnd)  
  207. public:  
  208.     CFrameWnd()  
  209.     {  
  210.         //cout<<"CFrameWnd constructor"<<endl;  
  211.   
  212.     }  
  213.     ~CFrameWnd()  
  214.     {  
  215.         //cout<<"CFrameWnd destructor"<<endl;  
  216.     }  
  217. public:  
  218.     virtual bool Create()  
  219.     {  
  220.         cout<<"CFrameWnd::Create"<<endl;  
  221.         CreateEx();  
  222.         return true;  
  223.     }  
  224.     virtual bool PreCreateWindow()  
  225.     {  
  226.         cout<<"CFrameWnd::PreCreateWindow"<<endl;  
  227.         return true;  
  228.     }  
  229. };  
  230. IMPLEMENT_DYNCREATE(CFrameWnd,CWnd)  
  231.   
  232. class CWinThread:public CCmdTarget  
  233. {  
  234. public:  
  235.     CWinThread()  
  236.     {  
  237.         //cout<<"CWinThread constructor"<<endl;  
  238.     }  
  239.     ~CWinThread()  
  240.     {  
  241.         //cout<<"CWinThread destructor"<<endl;  
  242.     }  
  243. public:  
  244.     virtual bool InitInstance()  
  245.     {  
  246.         cout<<"CWinThread::InitInstance"<<endl;  
  247.         return true;  
  248.     }  
  249.     virtual bool Run()  
  250.     {  
  251.         cout<<"CWinThread::Run"<<endl;  
  252.         return true;  
  253.     }  
  254. };  
  255. class CWinApp:public CWinThread  
  256. {  
  257. public:  
  258.     CWinApp()  
  259.     {  
  260.         //cout<<"CWinApp Constructor "<<endl;  
  261.         m_currentApp=this;  
  262.     }  
  263.     ~CWinApp()  
  264.     {  
  265.         //cout<<"CWinApp destructor "<<endl;  
  266.     }  
  267.     virtual bool InitApplication()  
  268.     {  
  269.         cout<<"CWinApp::InitApplication"<<endl;  
  270.         return true;  
  271.       
  272.     }  
  273.     virtual bool InitInstance()  
  274.     {  
  275.         cout<<"CWinApp:InitInstance"<<endl;  
  276.         return true;  
  277.     }  
  278.     virtual bool Run()  
  279.     {  
  280.         cout<<"CWinApp::Run"<<endl;  
  281.         return CWinThread::Run();  
  282.     }  
  283. public:  
  284.     CWinApp*m_currentApp;  
  285.     CFrameWnd*m_currentFrameWnd;  
  286. };  
  287. class CDocument:public CCmdTarget  
  288. {  
  289. public:  
  290.     CDocument()  
  291.     {  
  292.         //cout<<"CDocument constructor "<<endl;  
  293.     }  
  294.     ~CDocument()  
  295.     {  
  296.         //cout<<"CDocunment destructor "<<endl;  
  297.     }  
  298. };  
  299. class CMyFrameWnd:public CFrameWnd  
  300. {  
  301.     DECLARE_DYNCREATE(CMyFrameWnd)  
  302. public:  
  303.     CMyFrameWnd()  
  304.     {  
  305.         //cout<<"CMyFrameWnd constructor "<<endl;  
  306.         Create();  
  307.     }  
  308.     ~CMyFrameWnd()  
  309.     {  
  310.         //cout<<"CMyFrameWnd destructor "<<endl;  
  311.     }  
  312. };  
  313. IMPLEMENT_DYNCREATE(CMyFrameWnd,CFrameWnd)  
  314.   
  315. class CMyWinApp:public CWinApp  
  316. {  
  317. public:  
  318.     CMyWinApp()  
  319.     {  
  320.         //cout<<"CMyWinApp constructor "<<endl;  
  321.           
  322.     }  
  323.     ~CMyWinApp()  
  324.     {  
  325.         //cout<<"CMyWinApp destructor "<<endl;  
  326.     }  
  327. public:  
  328.     bool InitInstance()  
  329.     {  
  330.         cout<<"CMyWinApp::InitInstance"<<endl;  
  331.         m_currentFrameWnd=new CMyFrameWnd;  
  332.         return true;  
  333.     }  
  334. };  
  335.   
  336. CMyWinApp myApp;  
  337. CWinApp*AfxGetApp()  
  338. {  
  339.     return myApp.m_currentApp;  
  340. }  
  341. int main(int argc,char**argv)  
  342. {  
  343.     CWinApp *pApp=AfxGetApp();  
  344.     pApp->InitApplication();  
  345.     pApp->InitInstance();  
  346.     pApp->Run();  
  347.   
  348.     CRuntimeClass *pClass;  
  349.     CObject *pOb;  
  350.     cout<<"以下为类型型录链表中的所有类的名称:"<<endl;  
  351.     for(pClass=CRuntimeClass::pFirstClass;pClass;pClass=pClass->m_pBaseClasss)  
  352.     {  
  353.         cout<<pClass->m_lpszClassName<<endl;  
  354.     }  
  355.     while(1)  
  356.     {  
  357.         pClass=CRuntimeClass::Load();  
  358.         if(!pClass)  
  359.         {  
  360.             cout<<"找不到此类!!!"<<endl;  
  361.         }  
  362.         else  
  363.         {  
  364.             pOb=pClass->CreateObject();  
  365.             if(pOb)  
  366.             {  
  367.                 cout<<"创建成功!"<<endl;  
  368.             }  
  369.   
  370.         }         
  371.     }  
  372.     return 0;  
  373. }</span>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值