C++程序架构.docx
《C++程序架构.docx》由会员分享,可在线阅读,更多相关《C++程序架构.docx(13页珍藏版)》请在冰豆网上搜索。
C++程序架构
C++程序架构
目录
一、 引言
二、 C++程序架构的基本元素 -类
三、 C++程序开发过程
四、 MFC知识介绍
(1)MFC是一个编程框架
(2)MFC的宏观框架体系
(3)MFC对象的创建过程
3.1创建关系
3.2创建程序步骤
3.3常用的类的层次
3.4MFC运行层次结构图
3.5WinMain入口函数
五、MFC程序流程
一、引言
应用程序也像一个建筑物,有它的架构,建筑物是有层次,模块,和基本元素,如砖块,或模版组成的。
程序也非常相似,类就是C++程序架构的基本元素。
程序是运行在计算机上的,而计算机必须有一个操作系统,我们把操作系统看作是一个平台,程序就是运行在这个平台上,就像建筑物总是起在一定的基础上一样。
操作系统提供了许多程序编程接口,API 。
应用程序通过API 调用操作系统许多内置的功能。
二、C++程序架构的基本元素 -类
C++程序是由一个一个类组成的,每一个类它可能是基类或者派生类,每一个类都封装了程序接口或者应用程序的概念等等,都有相应的功能和作用。
通过类的继承,可以使用基类的特性,或者派生出其他的特性。
使用虚拟函数和消息机制提供丰富的编程接口和控制。
一个程序的入口点是其主函数,主函数的主要任务是完成一些初始化的工作和维护一个消息循环。
通过主函数进入程序入口(如果编写的是基于Windows系统的程序,程序中将WinMain()函数作为应用程序的入口),根据主函数要求初始化窗口,发送消息调用其他的类,而类里封装着小程序或者低级的系统应用程序,然后完成类里的程序运行,这个过程也是对消息循环的维护。
当按照发送消息的要求完成每一个类的调用,也就完成了一个程序。
C++程序启动和初始化过程是创建对象、建立各种对象之间的关系、把窗口显示在屏幕上的过程。
而退出程序是关闭窗体销毁对象的过程。
如果程序是MFC的Windows应用程序,程序使用WinMain()函数作为入口,这个函数已经通过封装隐藏与应用程序框架中。
除WinMain()外,类似于CWinApp类成员函数Run()也是隐含执行的,Run()函数负责把消息放进应用程序窗口消息循环中,由WinMain()函数完成对Run的调用。
当WinMain()函数寻找到应用程序对象后立即调用CWinApp类的虚函数InitInstance()进行重载,以知道究竟需要何种窗体框架。
然后调用注册窗口类,进而调用LoadFrame()函数载入框架,使用派生类:
:
Create()创建应用程序框架,接着创建程序窗口。
使用显示更新函数显示更新程序窗口。
C++的类的调用过程也就是它的工作流程,也可以理解为类的消息循环,也就构成程序的框架。
而这种消息的传送也就符合Windows应用程序的特点,消息驱动。
如果我们要与程序交互的话,需要做的仅仅是选择适当的时机上系统产生消息了。
C++的模块和元素的运行法则事件驱动。
C++的模块和元素之间的通讯 消息机制。
Windows消息机制
三、C++程序开发过程
根据问题建立模型,编写.h头文件、项目配置文件、.cpp源文件,然后预编译、编译,链接库文件,最后生成可执行程序。
链接过程是将.obj目标代码和.lib函数库、类库合理有机组成.exe执行文件。
(如下图)
四、MFC知识介绍
以MFC为例子,简单谈下自己对它的一些了解:
(1)MFC是一个编程框架
MFC(MicrosoftFoundationClassLibrary)中的各种类结合起来构成了一个应用程序框架,它的目的就是让程序员在此基础上来建立Windows下的应用程序,这是一种相对SDK来说更为简单的方法。
因为总体上,MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓。
MicrosoftVisualC++提供了相应的工具来完成这个工作:
AppWizard可以用来生成初步的框架文件(代码和资源等);资源编辑器用于帮助直观地设计用户接口;ClassWizard用来协助添加代码到框架文件;最后,编译,则通过类库实现了应用程序特定的逻辑;
(2)MFC的宏观框架体系
MFC实现了对应用程序概念的封装,把类、类的继承、动态约束、类的关系和相互作用等封装起来。
这样封装的结果对程序员来说,是一套开发模板(或者说模式)。
针对不同的应用和目的,程序员采用不同的模板。
例如,SDI应用程序的模板,MDI应用程序的模板,规则DLL应用程序的模板,扩展DLL应用程序的模板,OLE/ACTIVEX应用程序的模板,等等。
这些模板都采用了以文档-视为中心的思想,每一个模板都包含一组特定的类。
典型的MDI应用程序的构成将在下一节具体讨论。
为了支持对应用程序概念的封装,MFC内部必须作大量的工作。
例如,为了实现消息映射机制,MFC编程框架必须要保证首先得到消息,然后按既定的方法进行处理。
又如,为了实现对DLL编程的支持和多线程编程的支持,MFC内部使用了特别的处理方法,使用模块状态、线程状态等来管理一些重要信息。
虽然,这些内部处理对程序员来说是透明的,但是,懂得和理解MFC内部机制有助于写出功能灵活而强大的程序。
总之,MFC封装了Win32API,OLEAPI,ODBCAPI等底层函数的功能,并提供更高一层的接口,简化了Windows编程。
同时,MFC支持对底层API的直接调用。
MFC提供了一个Windows应用程序开发模式,对程序的控制主要是由MFC框架完成的,而且MFC也完成了大部分的功能,预定义或实现了许多事件和消息处理,等等。
框架或者由其本身处理事件,不依赖程序员的代码;或者调用程序员的代码来处理应用程序特定的事件。
MFC是C++类库,程序员就是通过使用、继承和扩展适当的类来实现特定的目的。
例如,继承时,应用程序特定的事件由程序员的派生类来处理,不感兴趣的由基类处理。
实现这种功能的基础是C++对继承的支持,对虚拟函数的支持,以及MFC实现的消息映射机制。
(3)MFC对象的创建过程
MFC程序启动和初始化过程就是创建MFC对象和Windows对象、建立各种对象之间的关系、把窗口显示在屏幕上的过程,退出过程就是关闭窗口、销毁所创建的Windows对象和MFC对象的过程。
所以,下面要讨论几种常用MFC对象的结构,它们是构成一个文档-视模式应用程序的重要部件。
(3.1)创建关系
(3.2)创建程序步骤
1)SDI应用程序的对象创建
程序从InitInstance开始,在SDI应用程序的InitInstance里,至少有以下部分:
第一部分,创建文档模板对象并把它添加到应用程序的模板链表
第二部分,动态创建文档、视、边框窗口等MFC对象和对应的Windows对象;
(1)、文档模板的创建
(2)、文件的创建或者打开
在创建工作完成之后,进行初始化,使用文档对象的数据来更新视和显示窗口。
至此,本节描述了MFC的SDI程序从分析命令行到创建或打开文件的处理过程,文档对象已经动态创建。
总结如下:
命令行分析→应用程序的FileNew→文档模板的OpenDocumentFile(NULL)→文档的OnNewDocument
命令行分析→应用程序的FileOPen→文档模板OpenDocumentFile(filename)→文档的OpenDocument
第三部分,返回TRUE,WinMain下一步调用Run开始消息循环,否则,终止程序;
2)视的创建
3)窗口初始化
4)视的初始化
5)激活边框窗口(处理WM_ACTIVE)
(3.3)常用的类的层次关系
————-参考《MFC教程》中MFC概述
—————
(3.4)MFC运行层次结构图
(3.5)WinMain入口函数
现在讨论MFC应用程序如何启动。
WinMain函数是MFC提供的应用程序入口。
进入WinMain前,全局应用程序对象已经生成。
WinMain流程如下图。
图中,灰色框是对被调用的虚拟函数的注释,程序员可以或必须覆盖它以实现MFC要求的或用户希望的功能;大括号所包含的图示是相应函数流程的细化,有应用程序对象App的初始化、Run函数的实现、PumpMessage的流程,等等。
——–图出自《MFC教程》第五章MFC对象的创建
——–
从图中可以看出:
(1)一些虚拟函数被调用的时机
对应用程序类(线程类)的InitIntance、ExitInstance、Run、ProcessMessageFilter、OnIdle、PreTranslateMessage来说,InitInstance在应用程序初始化时调用,ExitInstance在程序退出时调用,Run在程序初始化之后调用导致程序进入消息循环,ProcessMessageFilter、OnIdle、PreTranslateMessage在消息循环时被调用,分别用来过滤消息、进行Idle处理、让窗口预处理消息。
(2)应用程序对象的角色
首先,应用程序对象的成员函数InitInstance被WinMain调用。
对程序员来说,它就是程序的入口点(真正的入口点是WinMain,但MFC向程序员隐藏了WinMain的存在)。
由于MFC没有提供InitInstance的缺省实现,用户必须自己实现它。
稍后将讨论该函数的实现。
其次,通过应用程序对象的Run函数,程序进入消息循环。
实际上,消息循环的实现是通过CWinThread:
:
Run来实现的,图中所示的是CWinThread:
:
Run的实现,因为CWinApp没有覆盖Run的实现,程序员的应用程序类一般也不用覆盖该函数。
(3)Run所实现的消息循环
它调用PumpMessage来实现消息循环,如果没消息,则进行空闲(Idle)处理。
如果是WM_QUIT消息,则调用ExitInstance后退出消息循环。
(4)CWinThread:
:
PumpMessage
该函数在MFC函数文档里没有描述,但是MFC建议用户使用。
它实现获取消息,转换(Translate)消息,发送消息的消息循环。
在转换消息之前,调用虚拟函数PreTranslateMessage对消息进行预处理,该函数得到消息目的窗口对象之后,使用CWnd的WalkPreTranslateTree让目的窗口及其所有父窗口得到一个预处理当前消息的机会。
关于消息预处理,见消息映射的有关章节。
如果是WM_QUIT消息,PumpMessage返回FALSE;否则返回TRUE。
五、MFC程序流程
1:
applicationobject产生
2:
AfxWinMain执行AfxWininit,调用AfxinitThred
3:
AfxWinMain执行InitApplication,Initinstance(是Cwinapp虚函数)
4:
CMyWinApp:
:
InitInstance new 一个CMyFrameWnd
5:
CMyFrameWnd构造函数调用Create产生主窗口
6:
InitInstance执行ShowWindow,UpdateWindow,发出WM_PAINT
7:
AfxWinMain执行run
8:
:
:
GetMessage,WM_PAINT由:
:
DispatchMessage送CWnd:
:
DefWindowProc–>MessageMap
9:
调用对应函数(BEGIN—MESSAGE—MAP,END_MESSAGE_MAP建立的)
10:
单击file/close,则发出WM—CLOSE
11:
CMyFrameWnd交默认处理
12:
调用:
:
DestroyWindow发出WM_DESTROY
13:
默认处理调用:
:
postQuitMessage 发出WM_QUIT
14:
CWinapp:
:
Run收到WM—QUIT结束内部循环,调用ExitInsance(若CMyWinApp改写Exitinstance,则调用CMyWinApp:
:
ExitInstance;
15:
回到AfxWinMain,执行AfxWinTerm,程序结束!