MFC中所有的对象以CObject为根,CObject派生出一些类:CCmdTarget、CWnd、CDocument。具体的层次关系如下:
图(1)MFC的层次关系
本案例以MFC程序代码为蓝本,采用Win32 Console Application程序(即控制台应用程序),来仿真MFC的内部行为,当然省略了消息映射和消息循环。
新建一个Console工程,名称为Frame1,详细代码如下:
//mfc.h
#include <iostream.h>
class CObject
{
public:
CObject::CObject(){cout<<"CObject Constructor \n";}
CObject::~CObject(){cout<<"CObject Destructor \n";}
};
class CCmdTarget:public CObject
{
public:
CCmdTarget::CCmdTarget(){cout<<"CCmdTarget Constructor \n";}
CCmdTarget::~CCmdTarget(){cout<<"CCmdTarget Destructor \n";}
};
class CWinThread:public CCmdTarget
{
public:
CWinThread::CWinThread(){cout<<"CWinThread Constructor \n";}
CWinThread::~CWinThread(){cout<<"CWinThread Destructor \n";}
};
class CWinApp:public CWinThread
{
public:
CWinApp* m_pCurrentWinApp;
public:
CWinApp::CWinApp(){
m_pCurrentWinApp=this;
cout<<"CWinApp Constructor \n";
}
CWinApp::~CWinApp(){cout<<"CWinApp Destructor \n";}
};
class CDocument:public CCmdTarget
{
public:
CDocument::CDocument(){cout<<"CDocument Constructor \n";}
CDocument::~CDocument(){cout<<"CDocument Destructor \n";}
};
class CWnd:public CCmdTarget
{
public:
CWnd::CWnd(){cout<<"CWnd Constructor \n";}
CWnd::~CWnd(){cout<<"CWnd Destructor \n";}
};
class CFrameWnd:public CWnd
{
public:
CFrameWnd::CFrameWnd(){cout<<"CFrameWnd Constructor \n";}
CFrameWnd::~CFrameWnd(){cout<<"CFrameWnd Destructor \n";}
};
class CView:public CWnd
{
public:
CView::CView(){cout<<"CView Constructor \n";}
CView::~CView(){cout<<"CView Destructor \n";}
};
//global function
CWinApp* AfxGetApp();
#include "my.h"
extern CMyWinApp theApp;
CWinApp* AfxGetApp()
{
return theApp.m_pCurrentWinApp;
}
//my.h
#include<iostream.h>
#include "mfc.h"
class CMyWinApp:public CWinApp
{
public:
CMyWinApp::CMyWinApp(){cout<<"CMyWinApp Constructor \n\n";}
CMyWinApp::~CMyWinApp(){cout<<"CMyWinApp Destructor \n";}
};
//my.cpp
#include "my.h"
CMyWinApp theApp; //global object
void main()
{
CWinApp* pApp = AfxGetApp();
}
运行效果如下:
解析:
于是,你看到了,Frame1并没有new 任何对象,反倒是有一个全局对象 theApp存在,C++规定:全局对象的构建将比程序进入点(在DOS环境为main,在Windows环境为WinMain)更早,所以theApp 的构造函数将早于main()函数。即,上述构造函数的输出操作(XXX Constructor )都是在main()函数之前完成的。
main()函数调用全局函数AfxGetApp()来获得theApp的对象指针,这完全是仿真MFC程序的手法。
参考文献:侯俊杰.深入浅出MFC(第二版).武汉.华中科技大学出版社,2001