In me the tiger sniffs the rose.” 心有猛虎,细嗅蔷薇。
人心拥有猛虎和蔷薇的两面体,若缺少了蔷薇就难免变得莽撞,从而流入庸俗;若缺少了猛虎就难免变得懦弱,从而失去气魄。
一、面向对象的概念
1、面向对象(Object-Oriented Program)更加符合人们认识世界实物的逻辑思维,更能充分使用和运用人们已经掌握的知识系统,尤其对于大型系统,函数式编程难以描述倾城系统的架构,而面向对象则可解决这一问题,规模越大其体现的优势也越大。
2、面向对象编程(OOP)是当前主流的程序设计范型,是一种编程语言模式,它已经取代了结构化、过程化程序设计开发技术,因为结构化的开发方法制约了软件的可维护性和可扩展性。
3、面向对象编程的组织方式围绕“对象”,而不是围绕“行为”;围绕“数据”,而非“逻辑”。
4、面向对象程序采用的观点是“一切都是对象”。
5、在OOP中,对象的范围囊括现实世界中客观存在的实体(Entity),人类潜意识已经按照实体的共同或相似特性将其分类(Class),而通常见到的实体是某个类的一个实例(Instance)。
6、面向对象分析(OOA,Object-Oriented Analysis)就是以“类”的概念去认识问题、分析问题。
7、面向对象设计(OOD,Object-Oriented Design)是在OOA的基础上进行数据建模,从而建立所要操作的对象以及它们之间的联系。
8、OOP则是在前两者的基础上,对数据模型进一步细化,定义它包含的数据的类型和任何能够操作它的逻辑程序,每个不同的逻辑程序被认为是一个方法。
实际应用中,一个类的现实实例被称作一个“对象”,或者被称作类的一个“实例”。
9、对象或者类实例是要在程序中使用和运行的,它的方法对应于计算机指令,它的属性提供相应的数据,通过方法的调用来操作相应的数据,从而使数据得以保护,是开发者与数据隔离二无需获知数据的具体格式。
10、面向对象编程语言有三个基本特征:封装、继承和多态。
11、封装
封装就是把对象的属性(状态)和方法(行为)结合在一起,并尽可能隐蔽对象的内部细节,形成一个不可分割的独立单位(即对象),对外形成一个边界,只保留有限的对外接口使之与外部发生联系。
12、继承
继承是软件重用的一种形式,它通过吸收现有类的数据(属性)和方法,并增加新功能或修改现有功能来构建新类。
在C++语言中,通常称一般类(如:“人”)为父类,也称为超类;特殊类(如:“学生”和“老师”)成为子类,特殊类的对象拥有其一般类的全部属性与方法。
13、多态
多态性是指在父类中定义的属性或方法被子类继承之后,可能具有不同的表现行为。这使得同一个属性或方法在父类及其各个子类中具有不同的语义。
C++编程语言中可以通过子类对父类方法的重写实现多态,也可以利用函数重载,在同一个类中定义多个函数名相同、参数不同的方法来实现多态。
多态的引入大大提高了程序的抽象程度和简洁性,更重要的是它最大限度地降低了类和程序模块之间的耦合,提高了类模块的封闭性,使得他们不需要了解对方的具体细节,就可以很好地共同工作。
二、类的定义
1、C++中的类定义了一种新的数据类型。 多个对象所共有的属性和操作需要组合成一个单元,称为“类”,因此类是具有相同属性和共同行为的一组对象的集合。
2、类一旦被定义,就可以用这种新类型来创建该类型的对象。累就是对象的模板,而对象就是类的一个实例。
3、类的属性和方法如下:
(1)类的属性:对象的特征在类中表示为成员变量,称为类的属性。例如,每一个雇员对象都有姓名、年龄和体重,它们是类中所有雇员共享的公共属性。
(2)类的方法:是类的成员函数,是对象执行操作的一种规范。方法指定以何种方式操作对象的数据,是操作的实际实现。
4、在C++中定义类的语法格式如下:
5、类的定义一般会用两个文件来实现:一个是类的定义文件,在头文件(.h)中实现;另一个是类的构造方法、成员函数的具体实现,用源文件(.cpp)实现。在类的实现文件中,类的成员函数的定义语法格式如下:
6、定义完一个类后,可以创建该类型的对象,即对该类进行实例化。如果想在创建对象时就能完成属性的初始化操作,可通过类的特殊成员——构造函数。构造函数是对象创建时用于初始对象的特殊成员函数。
构造函数有两点不同:
(1)构造函数具有和它所在的类完全一样的名字;
(2)构造函数没有返回类型;
7、创建对象有两种方法:栈对象和堆对象
栈对象离开作用域后,所占内存由系统自动收回;
堆对象在离开作用域后所占内存并不会自动释放,必须手动释放,例如使用delete语句释放new运算符所创建的堆对象。
8、在用派生类实例化对象时,基类和派生类的构造函数和析构函数的调用顺序如下:
(1)构造时,先调用基类的构造函数,然后是派生类的构造函数;
(2)析构时,正好相反,先调用派生类的析构函数,然后是基类的析构函数。
9、this指针是指向一个对象地址的指针。this是一种隐含指针,它隐含于每个类的非静态成员函数中,即每个非静态成员函数都有一个this指针变量,this指针指向该成员函数所属类的对象。
10、C++支持类的继承。在C++中,被继承的类叫基类或父类,继承基类的类叫派生类或子类。
三、Win32编程
1、基于窗体的Windows应用程序,在32位CPU上,基于窗体的Windows程序称为Win32程序。
2、应用程序如何通知操作系统执行某个功能呢?一般来说在应用中要完成某个功能,都是以函数调用的形式实现的。同样的,应用程序也是以函数调用的方式通知操作系统执行相应的功能的,而且操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,也就是说,操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,从而完成系统调用的目的,这些函数的集合就是Window操作系统提供给应用程序编程接口(API),简称
Windows API(Application Programming Interface)。如调用CreateWindow()函数,操作系统就会按照还函数提供的参数信息在屏幕上产生一个相应的窗口。
3、要想使用Windows API开发程序,需要先安装SDK(Software Development Kit),一般的IDE开发环境中都集成了SDK,如Visual Studio。
4、Windows SDK包括API函数声明所在的头文件、链接库、帮助文档、辅助工具等,即SDK是开发程序所需资源的一个集合。
5、Windows程序采用的是事件驱动方式的程序设计模式,能被操作系统或者窗口感知、识别的操作称为事件,操作系统通过消息机制(Message)将感知到的事件传递给应用程序。
6、在应用程序启动后,系统等待用户在图形用户界面(窗体)内的输入事件,如鼠标按键、键盘按键、窗体创建、窗体关闭、窗体改变大小移动等,对系统而言这些都是事件。
7、操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序。只要有事件发生,系统即产生特定的消息。
8、多字节字符集(MBCS)、双字节字符集(UNICODE);
SDK和MFC都能很好地同时支持MBCS、UNICODE。
由于MBCS的字符串表示是char*或char[],
而UNICODE的字符串表示是wchar_t*或wchar_t[];
9、为了方便编程,Windows新定义了数据类型TCHAR、LPTSTR、LPCTSTR,
其中,TCHAR用来代替char和wchar_t,
LPTSTR是TCHAR*,
而LPCTSTR是const TCHAR*;
(API, Application Programming Interface)
10.、在Windows.h中,几乎所有用于处理字符串的API函数都使用TCHAR、LPTSTR、LPCTSTR三种数据类型。如果需要使用TCHAR等数据类型,在用SDK编程时需要包含tchar.h头文件,并且const TCHAR*或LPCTSTR(常量字符串)需要用到宏“_T”。
四、源程序组成结构
1、Windows应用程序具有相对固定的基本结构,其中有入口函数WinMain()、窗口函数WndProc()构成基本框架,并包含各种其他数据、函数等。入口函数和窗口函数是应用程序的主体。
2、入口函数WinMain()是所有Windows应用程序的入口,主要功能是注册窗口类、创建显示窗口以及产生消息循环。
○定义窗口类对象;窗口的特征是由WNDCLASS结构体来定义的;再结构体定义一个结构体对象,然后填写相应的结构体成员,即可设计窗口特征;
○注册窗口类;窗口类对象定义完成后,需要调用RegisterClass()函数对其进行注册;
○创建窗口实例;窗口类注册完成后,就可以用CreateWindow()函数创建窗口类的实例了,也就是创建具体的窗口;
○显示及更新窗口
3、CreateWindow()函数的原型如下:
CreateWindow()函数的dwStyle参数是具体要创建的窗口的样式;
4、消息循环,要从消息队列中取出消息,需要调用GetMessage()函数,原型如下:
只要从消息队列中取出的消息不为WM_QUIT,GetMessage()函数返回的是一个非零值,否则返回0;
5、窗口函数,是完成WinMain函数的编写后,还需要指定这个窗口的过程函数,又称为回调函数。
回调函数处理原理:当应用程序收到某一窗口的消息时,就应该调用某一函数来处理这条消息,这一调用过程不用应用程序自己来实施,而由操作系统完成,但是,回调函数本身的代码必须由应用程序完成。对于一条消息,操作系统到底调用应用程序中的哪个函数来处理呢?于是Windows约定,由窗口的lpfnWndProc成员指定的函数来处理,应用程序的这个函数不是用户自己调用的,而是写好了程序处理逻辑,经由lpfnWndProc指定后,由操作系统完成调用。
窗口函数的名字有程序员定义,但要注意函数的返回值和参数表必须符合Windows操作系统的要求,窗口函数的原型如下:
6、利用WNDCLASS类的lpfnWndProc()成员函数保存的窗口函数指针调用窗口函数,已处理消息。
五、GDI绘图
1、GDI是图形设备接口(Graphic Device Interface)将物理显示硬件和软件程序分离、解耦,不允许程序直接访问物理显示硬件,而是通过称为“硬件环境”的抽象结构间接访问。
2、Windows应用程序中的所有绘图操作,包括窗体本身的显示都要调用GDI来实现。GDI处理来自Windows应用程序的图形函数调用,然后把这些调用传递给合适的设备驱动程序,由设备驱动程序来执行与硬件(显卡)想过的操作并产生最后的输出结果。
3、所有的绘制操作都是通过GDI中的设备描述表(简称DC,设备上下文,Device Context)进行的,设备描述表对应的数据类型是HDC。HDC句柄是DC的资源标识符。
4、Windows应用程序—》设备描述表(DC)—》图形设备接口(GDI)—》设备驱动程序。
六、MFC基础
1、单纯的使用Windows API进行编程时,大量的代码需要用户自己编写,工作量较大。利用MFC和向导来编写Windows应用程序会简化很多。
2、MFC(Microsoft Foundation Class Library)是微软基础类库的简称。
3、MFC的目的就是让程序员在MFC基础上来建立Windows下的应用程序,MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓。
4、CObject根类的最基本功能是支持串行化(serialization)、运行时(Run-time)类的信息获取、提供特定操作符以及完成对象的建立与删除。
CObject派生类层次示意图:
CObject根类(1、CCmdTarget类;
2、CDC设备环境类;(CClientDC、CWindowDC、CPaintDC)
3、CGDiObject绘图对象类;(CPen、Cbrush、CFont、CBitmap)
4、CMenu菜单类;
5、Carray、Clist、Cmap…集合类;
6、Cdatabase、Crecordset…ODBC数据库支持类;
7、CFile文件类;)
5、CCmdTarget类(命令标靶类,command target)是MFC库中所有具有消息映射类的基类。CCmdTarget类还派生出了应用程序框架所需要的类。
CCmdTarget派生类层次示意图:
CCmdTarget命令相关类(1、CWinThread线程类;(CWinApp应用程序类)
2、CDocument文档类;
3、CDocTemplate文档模板类;(CSingle/MultiDocTemplate单/多文档模板类)
4、CWnd窗口类;(CFrameWnd框架窗口类、CView视图类、CDialog对话框类))
6、将消息和表格中的元素比较,然后调用对应的处理程序,这种操作称为消息映射(MessageMapping)。
7、文档是应用程序数据基本元素的集合,它构成应用程序所使用的数据单元;
视图是数据显示单元。
Windows操作系统提供的记事本程序就是单文档程序;
Word程序就是多文档程序;
8、串行化是指将对象保存到存储介质上(比如磁盘)或从存储介质读取并重新构造对象的过程。
CObject类定义了两个在串行化过程中起重要作用的成员函数:Serialize()函数和IsSerializable()函数。
Serialize()函数用于将对象串行化;
IsSerializable()函数用于确定该对象是否支持串行化操作;
9、CDialog是对Windows对话框的封装。可以直接使用CDialog类实例化对象然后调用相关成员的成员函数以创建对话框。
CDialog还派生了一个CCommonDialog类。该类有派生了一些用于特殊用途的对话框,这些类提供了标准的Windows对话框支持,例如
△ CFileDialog:打开或保存文件对话框类;
△ CColorDialog:选择颜色对话框类;
△ CFontDialog:选择字体对话框类;
△ CPrintDialog:打印文件对话框类;
△ CFindReplaceDialog:查找、替换操作对话框类;
10、GDI是Windows图像设备接口,使用GDI直接绘图比较繁琐,MFC对GDI操作进行了进一步的封装,简化了使用方法。封装主要体现在三个方面:
(1)CDC(DC,设备描述表)及其派生类;
(2)图形对象类;
(3)绘图有关的数据类型;
11、// 创建新笔(实线/虚线,1个/2个像素宽,颜色)
CreatePen(PS_SOLID/PS_DASH,1/2,RGB(255,255,255))
12、combinator:协调器、连接符、组合子
13、MFC对GDI绘图对象的封装给使用带来了方便,可以调用构造函数或成员函数对象,并设置对象属性(颜色),对象被销毁时析构函数会自动释放做占用的系统内存。
MFC绘图对象类的主要成员函数及功能
对象 | MFC类 | 创建方法 |
画笔 | CPen | 调用构造函数或CreatePen()和CreatePenIndirect()成员函数 |
画刷 | CBrush | 调用构造函数或CreateBrushIndirect()、CreateSolidBrush()等函数 |
字体 | CFont | 调用CreateFont()、CreateFontIndirect()等成员函数 |
位图 | CBitmap | 一般调用LoadBitmap()函数从资源中加载位图 |
调色板 | CPalette | 调用CreatePalette()或CreateHalftonePalette()成员函数 |
区域 | CRgn | 调用以Creae开头的成员函数 |
在使用MFC绘图对象时要遵守一定的规则:
- 创建对象:调用构造函数实例化对象,若构造函数没有创建相应的GDI对象,则要调用成员函数进一步创建。
- 调用CDC类的SelectObject选入DC;
- 调用CDC类的成员函数绘图;
- 恢复原来的对象;
对象离开作用域,自动释放绘图对象,进一步有系统自动实现;
七、MFC文档/视图
1、文档/视图结构是MFC中结构最复杂、体系最庞大而又最富有的特色的部分。
Document/View也被称为Model-View_Controller(MVC)文档视图模板;
2、Document在MFC的CDocument中被实例化,用来承载(容纳)数据,并至少提供专门负责文件读/写操作的Serialize函数的类;
View负责描述或呈现Document中的数据,它有两个最重要的任务:一是负责数据的显示;
另一个是负责数据的编辑。
3、文档/视图结构简单化了多数应用程序的设计开发过程,主要的优点试讲数据操作、数据显示和用户界面分离开;
MFC在文档/视图结构上提供了许多标准操作(如新建文件、打开文件、保存文件、打印等操作),它们被框架自动完成,减轻了开发者的工作量,不必编写这些代码,从而可以把更多的精力放到应用程序特定功能的代码上。
4、MFC将文档/视图程序分为两类:单文档程序(SDI)和多文档程序(MDI)。
5、△ CWinApp类:应用程序类,是非窗体类。该类的派生类实例化一个全局对象。CWinApp类对象是应用程序的起点,负责应用程序的启动。
△ CFrameWnd类:框架窗口类,是应用程序的框架窗口。所谓框架窗口是指包括菜单、工具栏、状态栏和窗口客户区的整个应用程序的主窗口。该类的派生类对象是在InitInstance()函数内实例化的。
△ CView类:视图窗口类,专门用来对应用程序的数据进行显示。视图类中有一个很重要的成员函数OnDraw(),已完成视图类的数据显示工作。
△ CDocument类:文档类,是非窗体类。
△ CDocTemplate类:文档模板类,是非窗体类。其作用是建立文档/视图结构中的文档类、视图类和框架窗口类之间的关系