接上一篇:MFC关键技术模拟(1)
http://blog.youkuaiyun.com/bzhou830/article/details/25505291
上次仿真了MFC的类层次结构,这次开始仿真MFC程序的初始化过程。首先给出类的继承和包含的函数图表。这种图表方式可能相比资源框里面的那种方式更加容易理解。
按照这个图表,在上一次的源码上添加成员函数。
mfc.h
#include <iostream>
using namespace std;
class CObject
{
public:
CObject::CObject()
{
cout<<"CObject Constructor"<<endl;
}
CObject::~CObject()
{
cout<<"CObject Destructor"<<endl;
}
};
class CCmdTarget : CObject
{
public:
CCmdTarget::CCmdTarget()
{
cout<<"CCmdTarget Constructor"<<endl;
}
CCmdTarget::~CCmdTarget()
{
cout<<"CCmdTarget Destructor"<<endl;
}
};
class CWinThread : public CCmdTarget
{
public:
CWinThread::CWinThread()
{
cout<<"CWinThread Constructor"<<endl;
}
CWinThread::~CWinThread()
{
cout<<"CWinThread Destructor"<<endl;
}
virtual void CWinThread::InitInstance()
{
cout<<"CWinThread::InitInstance"<<endl;
}
virtual int CWinThread::Run()
{
cout<<"CWinThread::Run"<<endl;
return 1;
}
};
class CWnd; //因为CwinApp类中添加了CWnd*类型,故在此需要做说明
class CWinApp : public CWinThread
{
public:
CWinApp * m_pCurrentWinApp;
CWnd* m_pMainWnd;
public:
CWinApp::CWinApp()
{
m_pCurrentWinApp = this;
cout<<"CWinApp Constructor"<<endl;
}
CWinApp::~CWinApp()
{
cout<<"CWinApp Destructor"<<endl;
}
virtual void CWinApp::InitApplication()
{
cout<<"CWinApp::InitApplication"<<endl;
}
virtual void CWinApp::InitInstance()
{
cout<<"CWinApp::InitInstance"<<endl;
}
virtual int CWinApp::Run()
{
cout<<"CWinApp::Run"<<endl;
return CWinThread::Run();
}
};
class CDocument:public CCmdTarget
{
public:
CDocument::CDocument()
{
cout<<"CDocument Constructor"<<endl;
}
CDocument::~CDocument()
{
cout<<"CDocument Destructor"<<endl;
}
};
class CWnd:public CCmdTarget
{
public:
CWnd::CWnd()
{
cout<<"CWnd Constructor"<<endl;
}
CWnd::~CWnd()
{
cout<<"CWnd Destructor"<<endl;
}
virtual void CWnd::Creat()
{
cout<<"CWnd::Creat"<<endl;
}
virtual void CWnd::PreCreatWindow()
{
cout<<"CWnd::PreCreatWindow"<<endl;
}
int CWnd::CreateEx()
{
cout<<"CWnd::CreateEx"<<endl;
PreCreatWindow();
return 1;
}
};
class CFrameWnd:public CWnd
{
public:
CFrameWnd::CFrameWnd()
{
cout<<"CFrameWnd Constructor"<<endl;
}
CFrameWnd::~CFrameWnd()
{
cout<<"CFrameWnd Destructor"<<endl;
}
void CFrameWnd::Creat()
{
cout<<"CFrameWnd::Creat"<<endl;
CreateEx();
}
virtual void CFrameWnd::PreCreatWindow()
{
cout<<"CFrameWnd::PreCreatWindow"<<endl;
}
};
class CView : public CWnd
{
public:
CView::CView()
{
cout<<"CView Constructor"<<endl;
}
CView::~CView()
{
cout<<"CView Destructor"<<endl;
}
};
CWinApp * AfxGetApp();
mfc.c
#include "my.h"
extern CMyWinApp theApp;
CWinApp * AfxGetApp()
{
return theApp.m_pCurrentWinApp;
}
my.h
#include <iostream>
#include "mfc.h"
class CMyFrameWnd :public CFrameWnd
{
public:
CMyFrameWnd::CMyFrameWnd()
{
Creat();
cout<<"CMyFrameWnd Constructor"<<endl;
}
CMyFrameWnd::~CMyFrameWnd()
{
cout<<"CMyFrameWnd Destructor"<<endl;
}
};
class CMyWinApp:public CWinApp
{
public:
CMyWinApp::CMyWinApp()
{
cout<<"CMyWinApp Constructor"<<endl;
}
CMyWinApp::~CMyWinApp()
{
cout<<"CMyWinApp Destructor"<<endl;
}
virtual void CMyWinApp::InitInstance()
{
cout<<"CMyWinApp::InitInstance"<<endl;
m_pMainWnd = new CMyFrameWnd;
}
};
my.c
#include "my.h"
CMyWinApp theApp;
void main()
{
CWinApp* pApp = AfxGetApp();
pApp->InitApplication();
pApp->InitInstance();
pApp->Run();
system("pause");
}
运行的结果:
这个运行结果和书上一致。下面来分析过程。
1、在程序进入main函数之前,构建了全局对象theApp,引发构造函数的执行。
2、进入main函数,CWinApp* pApp = AfxGetApp(); 这样pApp就指向了theApp全局对象。
3、 pApp->InitApplication();执行的是CWinApp::InitApplication();
4、pApp->InitInstance();执行的是CMyWinApp::InitInstance(); 因为CWinApp的子类CMyWinApp对虚函数InitInsyance进行了改写。
----CMyWinApp::InitInstance(); 中定义了 m_pMainWnd = new CMyFrameWnd;这样引发了CMyFrameWnd的构造函数的运行,当然之前会运行其父类的构造函数。
----然而在CMyFrameWnd的构造函数中调用Create()函数,由于Create()是虚函数,并且在CMyFrameWnd类中也没有对其进行改写,所以引发CFrameWnd类的Create函数。
---- CFrameWnd的Create函数又调用CreateEx()函数。他仅是一个父类成员函数,不是虚函数。所以就执行父类CWnd类的CreateEx();
----CWnd类的CreateEx();中执行PreCreateWindow()函数,这又是一个虚函数,并且子类对其做了改写,那么就执行子类CFrameWnd的PreCreateWindow()函数。
5、pApp->Run();执行的是CWinApp::Run();
至此,整个过程就完成了。里面涉及的主要是虚函数,确实体现出了虚函数特点和用途。