c++课程设计-交互式绘图软件设计指导书

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1《C++面向对象程序设计》课程设计指导书指导实例:交互式绘图软件设计指导书说明:1.本实例软件经设计实作,为可实际运行的软件。指导书中所列程序代码,均为VC++6.0编程环境中可运行代码复制所得,所列示图,均为制作过程中屏幕截图,其目的是使学习者尽快弄清设计原理,掌握过程、方法,起到举一反三、正真领会面向对象程序设计的思想方法,原理,和操作技能的作用。使用中,“1.设计原理”(第3页),供系统设计分析用,实际操作可从“2.操作过程与步骤”(第6页)开始。2.其余推荐题目,可根据自身实际情况,酌情参考使用。1.设计原理面向对象的程序设计是现在最外流行的程序设计方法。面向对象的方法模仿人们建立现实世界模型的方法,认为客观世界是由各种各样的对象组成的,每个对象都有各自的内部状态和运动规律,不同对象之间的相互作用和联系就构成了各种各样的系统。利用人们对事物分类和抽象的自然倾向,引进了类的概念,具有封装性、继承性和多态性等特点。面向对象的程序设计吸取了传统的结构化程序设计的优点,采用数据抽象和信息隐藏技术、将数据与操作封装在一起,用类来抽象代表现实的实体,用类之间的继承关系来代表设计的抽象过程,将问题求解看作是一个非类演绎过程。1.1类与数据封装在C++中,类是指由用户定义的一种抽象数据类型,将一组具有相关性的数据成员结合在一起,要使用类中所包含的数据时,必须通过有该类所提供的成员函数来存取。数据封装是指将类中的数据成员以其可被使用或不可被使用的方式进行分类,即有条件地限制类中部分或全部的数据成员被使用,在定义数据成员时在其前面冠以private、protected或public,分别表示私有的、保护的和公有的。因此,类是实现数据封装的一个有力方法,类的特性是实现了数据封装或数据抽象。在本设计中,可以把各种图形形状,如直线、矩形、圆、曲线、多边形等定义为各种各样的图形类,将图的具体绘制、存储操作和属性设置定义为图形类的public成员函数,这样就实现了类与数据封装。例如,直线类可以定义为:classCline{private:COLORREFm_color;//直线的颜色intm_lineWidth,m_lineStyle;//直线的线宽和直线的线型POINTm_beginPoint,m_endPoint;//直线的起点和终点public:COLORREFgetColor();//返回直线的颜色voidsetColor(COLORREFcolor);//设置直线的颜色2intgetLineStyle();//返回直线的线型voidsetLingStyle(UINTstyle);//设置直线的线型intgetLineWidth();//返回直线的线宽voidsetLineWidth(intwidth);//设置直线的线宽POINTgetBeginPoint();//返回直线的起点POINTgetEndPoint();//返回直线的终点voidDraw(CDC*pDC);//直线的具体绘制voidSerialize(CArchive&ar);…};1.2派生类与继承性在C++中,派生类和继承性是指用户可以利用已有的类(称为基类或父类)定义出新的类(派生类或子类),派生类中不但拥有基类中的全部或部分数据成员与成员函数,而且还可以定义新的数据成员与成员函数。在本设计中,要绘制的图形形状很多,如直线、矩形、圆、曲线、多边形等。虽然图形的形状差别很大,其数据成员和成员函数也有许多不同之处,但是如果从抽象的角度出发,它们有些数据成员和成员函数是相同的,如颜色、线型、线宽属性以及设置或获取这些属性的成员函数,因此可以把这些共同点定义为一个基类CShape,然后从CShape类派生出直线类、矩形类、圆类、曲线类、多边形类等,这样,每个派生类都继承有这些共同点,又可以定义自己独特的数据成员和成员函数,程序结构更加简练合理。CShape类的定义如下:classCShape{protected:COLORREFm_color;//颜色intm_lineWidth,m_lineStyle;//线宽和线型public:virtualCOLORREFgetColor();//返回颜色virtualvoidsetColor(COLORREFcolor);//设置颜色virtualintgetLineStyle();//返回线型virtualintsetLineStyle(intstyle);//设置线型virtualintgetLineWidth();//返回线宽virtualvoidsetLineWidth(intwidth);//设置线宽virtualvoidDraw(CDC*pDC);//绘图virtualvoidSerialize(Carchive&ar);//存储操作};而CLine类派生于CShape类,定义如下:classCLine:publicCShape{private:POINTm_beginPoint,m_endPoint;//直线的起点和终点public:3POINTgetBeginPoint();//返回直线的起点POINTgetEndPoint();//返回直线的终点voidDraw(CDC*pDC);//直线的具体绘制voidSerialize(Carchive&ar);//直线的具体存储操作…};1.3虚函数与多态性在面向对象中,多态性是指一个名字有多种含义,或相同界面有多种实现。在继承体系中,如果在派生类中对所继承的成员函数重新定义其功能,该函数应在基类中被定义为虚函数,在成员函数定义时在其前面加上关键字virtual。C++系统能自动判别应该调用哪一个类对象的成员函数。因此,虚函数是一种单界面多实现版本的方法,即函数名、返回类型、参数类型和个数及顺序完全相同,但函数体内容可以完全不同。在本设计中,可以把抽象的图形基类CShape的绘图操作Draw定义为虚函数,直线、矩形、圆、曲线、多边形等作为CShape的派生类,把它们的具体绘图操作定义在各自类中,保留其函数原型(函数名、返回值类型、参数个数及类型、顺序)都不变,然后用指向基类CShape的指针来调用Draw函数,就可以实现虚函数与多态性,即同样的调用语句因指针所指向的对象不同而画出不同的图像。如下所示:CShape*pShape;//定义指向基类CShape的指针pShapeCLineline;//定义一个直线类的对象linepShape=&line;//将line的地址赋给pShapepShape-Draw(pDC);//绘制直线Crectanglerect;//定义一个矩形类的对象rectpShape=▭//将CRectangle的地址赋给pShapepShape-Draw(pDC);//绘制矩形CCirclecircle;//定义一个圆对象circlepShape=&circle;//将circle的地址赋给pShapepShape-Draw(pDC);//绘制圆…可见,同样的语句“pShape-Draw(pDC);”,却能绘制出不同的图形,这就是虚函数与多态性的功能特点。1.4数据存储与屏幕重绘绘图程序Draw要求能用鼠标在屏幕上绘制直线、贝济埃曲线、圆、椭圆、矩形、多边形等基本二维图形,并提供相应的文件保存和屏幕重绘功能。二维图形包括许多种类型,用于表征这些二维图形对象的数据是不同的,它们都有颜色、线型和线宽3个属性数据,但它们的几何数据不同,点用一个坐标点数据表示,直线、圆、椭圆和矩形用两个坐标点数据表示,圆角矩形用两个坐标点数据和两个整型数据来表示,圆弧或椭圆弧、饼图或扇形用4个坐标点数据表示,贝济埃曲线用4个以上的坐标点数据表示,而多边形所需的坐标点数据个数是任意的。另外,对于封闭图形,还可以有填充与不填充选择,若填充,还可以选择颜色、影线和图案3种模式之一。因此,如何实现对这些具有不同数据类型和个数图形对象的保存,以及如何根据保存的数据区别不同图形对象并进行屏幕重绘,是本设计要解决的关键问题。从MFC的文档/视图结构可知,应用程序的数据保存专门由文档类的Serialize函数负责4具体完成,应用程序的数据显示或屏幕重绘专门由视图类的OnDraw函数负责具体完成。如果在二维图形基类CShape定义中把负责数据保存的成员函数Serialize和负责图形绘制的成员函数Drawing说明为虚函数,在派生类即具体的二维图形类定义中只对Serialize和Drawing的函数内容重新定义,保留其函数名、返回值类型和参数(包括类型和个数)不变,用一个指向基类CShape的指针访问虚函数Serialize和Drawing,就可以实现画图程序具有不同数据类型和个数的二维图形对象的保存,以及根据保存的数据区别不同图形对象在屏幕上重新绘制出来。在MFC类库中,集合类是专门用于数据保存的。集合类又分为数组类、链表类和映射类(也称数据字典类)。它们都能适用于各种数据类型,如BYTE、WORD、int、float、String、对象地址或对象指针等。从前面的分析可以看出,在画图程序中需要保存的数据是各二维图形对象的地址,因此可以选用数组类的CObArray/CPtrArray或链表类的CObList/CPtrList。在MFC中,数组是采用动态数组,链表是采用双向链表。数组和链表对存取数据的操作各有优缺点。在本设计中,可以简单地选用CObArray来存放二维图形对象的地址。1.5设计思路综上所述,可以总结设计思路如下:首先定义一个二维图形的基类CShape,它包含颜色、线型和线宽3个共有的数据成员,定义串行化Serialize和绘图Drawing两个虚函数,然后从CShape类派生上述各二维图形类:CLine、CCircle、CEllipse、CRectangle、CBezier和CPolygon等,在每一个二维图形类中定义自己的几何数据,定义构造函数以便生产各自的图形对象,重载Serialize和Drawing函数,以实现各自不同的数据序列化和屏幕重绘。其次,在文档类中定义一个可以保存各二维图形对象地址的CObArray数组,并定义3个操作该CObArray数组的文档类成员函数AddShape、GetShape、GetShapeNumber。视图类是使用这些函数的重要用户。在文档类的Serialize函数中简单地调用CObArray.Serialize函数,而CObArray的Serialize函数又依据所存放的对象指针类型调用相应类对象的Serialize函数,完成实际的数据读写操作,从而实现了二维图形对象不同数据类型和个数的序列化。再次,在用鼠标进行屏幕绘图的鼠标消息处理函数代码中,在OnLButtonUp函数内,对不同的二维图形对象,分别调用各自的构造函数生成二维图形对象,再把该二维图形对象地址用AddShape函数保存在CObArray数组中,以矩形为例,如下所示:if(CurrentDraw==DRAW_RECTANGLE){pShape=newCRectangle(m_pOrigin,point,m_pWidth,m_pStyle,m_pColor);}…//其他二维对象的相应语句段pDoc-AddShape(pShape);其中,pDoc为指向文档的指针;m_pWidth、m_pStyle和m_pColor为视图类的数据成员,分别代表二维图形的线宽、线型和颜色。最后,在OnDraw成员函数中定义一个基类CShape的指针变量pShape,采用循环方法遍历CObArray数组中的所有元素,在for循环内把调用GetShape函数获得的二维图形对象的地址赋给pShape,用pShape调用虚函数Drawing,就可以实现虚函数的多态性,即相同的pShape-Drawing(pDC)函数调用语句,由于pShape所指向的对象不同,实现了调用不同Drawing函数体内容的目的。从而在屏幕上绘出不同的二维图形。实现不同二维图形对象的数据保存和

1 / 34
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功