MFC框架之我见——模拟分析

                     MFC框架之我见——模拟分析

       复习MFC知识,再次翻看侯捷的《深入浅出》,下面是模拟MFC框架运行的代码 // // mfc.h // // // Written by Leezhm 27st August, 2008 // Contact : [email protected] // //------------CObject Class // | // |---CCmdTarget Class // | // |---CWinThread Class // | | // | |---CWinApp Class // | | // | |---CMyApp Class // | // |---CWnd // | | // | |---CView Class // | | | // | | |---CMyView Class // | | // | |---CFrameWnd Class // | | // | |---CMyFrameWnd Class // | // |---CDocument Class // | // |---CMyDoc Class #ifndef __H_MFC__ #define __H_MFC__ class CObject { public: CObject(); ~CObject(); }; class CCmdTarget : public CObject { public: CCmdTarget(); ~CCmdTarget(); }; class CWinThread : public CCmdTarget { public: CWinThread(); ~CWinThread(); public: virtual bool InitInstance(); virtual bool Run(); }; class CWnd; class CWinApp : public CWinThread { public: CWinApp(); ~CWinApp(); public: virtual bool InitApplication(); virtual bool InitInstance(); virtual bool Run(); public: CWinApp * m_pCurrentWinApp; CWnd * m_pMainWnd; }; class CWnd : public CCmdTarget { public: CWnd(); ~CWnd(); public: virtual bool Create(); bool CreateEx(); virtual bool PreCreateWindow(); }; class CView : public CWnd { public: CView(); ~CView(); }; class CFrameWnd : public CWnd { public: CFrameWnd(); ~CFrameWnd(); public: bool Create(); virtual bool PreCreateWindow(); }; class CDocument : public CCmdTarget { public: CDocument(); ~CDocument(); }; #endif //__H_MFC__ // // mfc.cpp // #include "mfc.h" #include <iostream> using std::cout; using std::endl; CObject::CObject() { cout<<"CObject Constructor"<<endl; } CObject::~CObject() { cout<<"CObject Destructor"<<endl; } CCmdTarget::CCmdTarget() { cout<<"CCmdTarget Constructor"<<endl; } CCmdTarget::~CCmdTarget() { cout<<"CCmdTarget Destructor"<<endl; } CWinThread::CWinThread() { cout<<"CWinThread Constructor"<<endl; } CWinThread::~CWinThread() { cout<<"CWinThread Destructor"<<endl; } bool CWinThread::InitInstance() { cout<<"CWinThread::InitInstance"<<endl; return true; } bool CWinThread::Run() { cout<<"CWinThread::Run"<<endl; return true; } CWinApp::CWinApp() { m_pCurrentWinApp = this; cout<<"CWinApp Constructor"<<endl; } CWinApp::~CWinApp() { cout<<"CWinApp Destructor"<<endl; } bool CWinApp::InitApplication() { cout<<"CWinApp::InitApplication"<<endl; return true; } bool CWinApp::InitInstance() { cout<<"CWinApp::InitInstance"<<endl; return true; } bool CWinApp::Run() { cout<<"CWinApp::Run"<<endl; return CWinThread::Run(); } CWnd::CWnd() { cout<<"CWnd Constructor"<<endl; } CWnd::~CWnd() { cout<<"CWnd Destructor"<<endl; } bool CWnd::Create() { cout<<"CWnd::Create"<<endl; return true; } bool CWnd::CreateEx() { cout<<"CWnd::CreateEx"<<endl; PreCreateWindow(); return true; } bool CWnd::PreCreateWindow() { cout<<"CWnd::PreCreateWindow"<<endl; return true; } CView::CView() { cout<<"CView Constructor"<<endl; } CView::~CView() { cout<<"CView Destructor"<<endl; } CFrameWnd::CFrameWnd() { cout<<"CFrameWnd Constructor"<<endl; } CFrameWnd::~CFrameWnd() { cout<<"CFrameWnd Destructor"<<endl; } bool CFrameWnd::Create() { cout<<"CFrameWnd::Create"<<endl; CreateEx(); return true; } bool CFrameWnd::PreCreateWindow() { cout<<"CFrameWnd::PreCreateWindow"<<endl; return true; } CDocument::CDocument() { cout<<"CDocument Constructor"<<endl; } CDocument::~CDocument() { cout<<"CDocument Destructor"<<endl; } // // myMFC.h // #ifndef __H_MYMFC__ #define __H_MYMFC__ #include "mfc.h" // global function CWinApp * myGetWinApp(); class CMyApp : public CWinApp { public: CMyApp(); ~CMyApp(); virtual bool InitInstance(); }; class CMyFrameWnd : public CFrameWnd { public: CMyFrameWnd(); ~CMyFrameWnd(); }; #endif //__H_MYMFC__ // // myMFC.cpp // #include "myMFC.h" #include <iostream> using std::cout; using std::endl; // global variable CMyApp theApp; CWinApp * myGetWinApp() { if(!theApp.m_pCurrentWinApp) return NULL; return theApp.m_pCurrentWinApp; } CMyApp::CMyApp() { cout<<"CMyApp Constructor"<<endl; } CMyApp::~CMyApp() { cout<<"CMyApp Destructor"<<endl; } bool CMyApp::InitInstance() { cout<<"CMyApp::InitInstance"<<endl; m_pMainWnd = new CMyFrameWnd(); return true; } CMyFrameWnd::CMyFrameWnd() { cout<<"CMyFrameWnd Constructor"<<endl; Create(); } CMyFrameWnd::~CMyFrameWnd() { cout<<"CMyFrameWnd Destructor"<<endl; } void main() { cout<<endl; CWinApp * pApp = myGetWinApp(); pApp->InitApplication(); pApp->InitInstance(); pApp->Run(); cout<<endl; }

      OK,代码贴完了,再看看运行的结果是么样的。

MFC框架之我见——模拟分析_第1张图片

        在这张图片中我们应该注意全局CMyApp对象的创建、销毁时的构造函数和析构函数的调用规范,以及各个函数的调用次序,要理解这些,需要理解class的继承、多态原理。

MFC框架之我见——模拟分析_第2张图片

        在这张图片中我们可以更实在地看到各个class的继承关系,还需要注意的是在子类中的虚拟函数表中各个函数的地址,是不是符合class的多态。

       

        好了,运行的结果以及调试结果都在上面。根据上面的来分析下:

        

        首先,关于全局变量theApp的创建过程中子类和父类的构造函数调用是符合C++语法的,先是最顶级父类构造函数,而后依次到最终的子类的构造函数;析构函数是刚好相反的。

        然后进入了main函数,首先会得到this指针,也即时全局变量theApp。

        pApp->InitApplication(...)调用,由于在CMyApp类中并没有对基类CWinApp中的虚拟函数进行重写(Override,也有叫覆盖,注意与类成员的重载区分开来),根据继承和多态原理,应该是调用的是CWinApp::InitApplication(...)函数

        pApp->InitInstance(...)调用,由于在CMyApp中继承并Override了基类的虚拟函数InitInstance函数,所以调用的是CMyApp::InitInstance(...)函数。注意在这个函数中语句:m_pMainWnd = new CMyFrameWnd();创建了CMyFrameWnd对象,这必然要引发一序列基类的构造的调用。

        还要注意的是在CMyFrameWnd的构造函数中调用了Create这个成员函数,Create函数又调用了CreateEx这个从基类继承的函数,而CreateEx函数中调用了PreCreateWindow函数。这个时候我们仔细看看源码,知道CFrameWnd从基类CWnd继承并重写了PreCreatWindow这个函数,所以这个时候调用的是CFrameWnd::PreCreateWindow(...)函数。理解这个数是一个关键点。

        最后Run函数的调用还是继承和多态原理,注意一下CWinApp::Run(...)的实现

  bool CWinApp::Run() { cout<<"CWinApp::Run"<<endl; return CWinThread::Run(); }

它返回的是CWinThread::Run(...),这就是这个地方不符合继承重写原理的原因。

 

         好了,整个分析完了,在下篇中将结合MFC的源码来分析整个模拟过程。

 

 

 

你可能感兴趣的:(框架,null,Class,mfc,Constructor,destructor)