MFC关键技术模拟(2)------MFC初始化过程

本文通过模拟MFC程序初始化过程,详细介绍了类继承关系及关键函数的调用流程。从全局对象构造到虚函数调用,逐步解析MFC应用程序启动过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          接上一篇: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();

至此,整个过程就完成了。里面涉及的主要是虚函数,确实体现出了虚函数特点和用途。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值