《面向对象程序设计实验指导书.pdf》由会员分享,可在线阅读,更多相关《面向对象程序设计实验指导书.pdf(23页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第 1 页面向对象程序设计(C+版)实验指导书西南交通大学信息科学与技术学院2009 年面向对象程序设计实验指导书第 I 页前言为了进一步加强和规范信息科学与技术学院本科学生面向对象程序设计的实践环节,特编写该实验指导书。该指导书配合面向对象理论与实践(文登敏,西南交通大学出版社,2005 年 6 月第一版)教材使用,以 C+语言作为背景,以 VC+6.0 作为实践环境。实验共分 10 次,约需实践(上机)时间 20-24 小时。前 9 次平均时间 2 小时,实验 10需要 4-6 小时。在 10 个实验中,实验 1 为环境熟悉结合环境编写和改写基于控制台的程序,并实现一个 windows 基
2、于对话框的示例。实验 2 为 C+基础,主要涉及到 new/delete、函数重载和引用数据类型方面。实验 3 到实验 7 是面向对象的核心部分,关系到封装、继承和多态三大机制和组合机制。实验 8 与运算符重载相关,通过该实验能够使学生深入领会 C+中运算符重载的精髓,以及通过结果分析进一步理解函数调用过程、对象运算过程以及临时对象的创建和撤销的内部实现机制。实验 9 是一个 DLL 组件封装的例子,可以为今后实现类封装奠定基础。实验 10 是一个综合性实验,结合一个人事管理系统的逐步设计和实现,使学生能够认识到如何采用面向对象程序设计方法编写一个能够快速适应需求变化的软件。为了使学生能够充分
3、理解面向对象的精髓,本指导书并未要求编写的程序是基于控制台的还是基于 windows 的,甚至是建议采用控制台程序设计,以避免过多地引入其它环境方面的内容从而影响实验的效果。每个实验都给出了实验报告的大致需求,通常都要求给出相应的源代码、运行结果及其对应关系。如果可能的话,建议在实验报告中给出实现的过程以及实验的感受。本指导书是在往届课内实验的基础上总结而成。随着时间的推移和技术的进步,相信还会在此基础上增减内容。面向对象程序设计实验指导书第 II 页目录前言.I实验 1熟悉环境.11.1 目的和要求.11.2 实验内容及参考过程.11.2.1 创建控制台工程.11.2.2 修改控制台程序.1
4、1.2.3 创建 windows 工程.11.3 实验报告.2实验 2C+基础.32.1 目的和要求.32.2 实验内容及参考过程.32.2.1 函数.32.2.2 new/delete.32.2.3 引用.42.3 实验报告.4实验 3类封装.53.1 目的和要求.53.2 实验内容.53.2.1 基础定义及函数.53.2.2 定义要求.53.2.3 主函数.53.2.4 运行程序分析结果.63.3 实验报告.6实验 4单继承.104.1 目的和要求.104.2 实验内容.104.2.1 创建子类.104.2.2 定义要求.104.2.3 主函数.104.2.4 运行程序分析结果.104.3
5、 实验报告.10实验 5多继承.115.1 目的和要求.115.2 实验内容.115.2.1 创建子类.115.2.2 定义要求.115.2.3 主函数.115.2.4 运行程序分析结果.115.2.5 虚继承.115.3 实验报告.12实验 6组合.136.1 目的和要求.13面向对象程序设计实验指导书第 III 页6.2 实验内容.136.2.1 创建部分类和整体类.136.2.2 主函数.136.3 实验报告.13实验 7多态与虚函数.147.1 目的和要求.147.2 实验内容.147.2.1 定义父类和子类.147.2.2 主函数.147.3 实验报告.14实验 8运算符重载.158
6、.1 目的和要求.158.2 实验内容.158.3 实验报告.15实验 9DLL 组件.169.1 目的和要求.169.2 实验内容.169.2.1 创建 DLL 工程.169.2.2 创建界面.169.2.3 创建调用 DLL 的程序.169.3 实验报告.16实验 10综合应用.1710.1 目的和要求.1710.2 实验内容.1710.3 实验过程.1710.3.1 创建工程.1710.3.2 设计思路.1710.3.3 代码封装及移植.1810.3.4 需求第一步.1910.3.5 需求第二步.1910.3.6 需求第三步.1910.3.7 需求第四步.1910.4 实验报告.19面向
7、对象程序设计实验指导书第 1 页实验1 熟悉环境1.1目的和要求l熟悉 VC+6.0 集成开发环境l能够编写简单控制台程序并运行产生相应结果l能够编写基于对话框的简单 windows 程序并运行产生结果1.2实验内容及参考过程1.2.1创建控制台工程l运行 VC+6.0 运行环境l创建基于控制台的应用程序工程l选择Hello World!程序l直接运行,产生结果l退出运行环境。1.2.2修改控制台程序l打开运行环境l打开上次创建的工程l找出源文件l加入头文件 iostream.hl将程序中的 printf(Hello World!n);修改成 cout”Hello 你自己的名字!”endl;l
8、运行并产生结果。l关闭当前工作空间1.2.3创建 windows 工程l新建一个 MFCAppWizard(EXE)工程。l创建的应用程序类型选择基本对话框(Base Dialog)l完成之后,双击窗口上的确定(OK)按钮,进入源程序l将 OnOK 函数修改成以下代码段(屏蔽 CDialog:OnOK();语句):MessageBox(”Hello 你的名字!”,“实验 1”);l运行,单击确定(OK)按钮,观察结果。l单击取消按钮(Cancel),退出运行。l在界面上增加感兴趣的控件,并编程实现之(选)。面向对象程序设计实验指导书第 2 页1.3实验报告lHello World 程序的源代码
9、和运行结果l修改后的控制台程序源代码和运行结果lWindows 程序 OnOK 函数源代码及运行结果界面截图l其它的程序修改和运行结果(选)l结果分析及实验感受面向对象程序设计实验指导书第 3 页实验2 C+基础2.1目的和要求l掌握 C+函数重载及缺省参数的使用l掌握 new 和 delete 的用法l掌握引用数据类型及其用法2.2实验内容及参考过程2.2.1函数l打开控制台工程(或创建新的控制台工程)l确保头文件中包含了 iostream.hl编写以下四个函数:void MyFunc()cout”无参数函数调用”endl;void MyFunc(int a)cout”1 个整型参数函数调用
10、”aendl;void MyFunc(int a,int b)cout”2 个整型参数函数调用”a”,”bendl;long MyCaculate(long a=10,long b=20)couta”,”bendl;return a*a+b*b;l在主函数 main 中加入以下调用语句:MyFunc();MyFunc(10);MyFunc(10,20);coutMyCaculate()endl;coutMyCaculate(1)endl;coutMyCaculate(1,2)endl;l运行并产生结果。分析结果。2.2.2new/deletel再增加一个函数:void TestNew()int
11、*p;p=new int2000;if(p)for(int i=0;i1000;+i)pi=i;delete p;面向对象程序设计实验指导书第 4 页l在主函数的最后增加以下循环语句:for(int i=0;i100000;+i)TestNew();l运行,观察机器内存和 CPU 占用率变化情况(在任务管理器中查看)。l退出运行,屏蔽 TestNew 函数中的 delete p;语句。l再次运行程序,观察机器内存和 CPU 占用率变化情况。l退出运行。l对比有无 delete p 语句的机器资源占用情况,分析。2.2.3引用l再增加一个结构和函数定义:struct S_Bigint a2000
12、0;char c80000;void TestRef(S_Big x)l将主函数修改成以下内容(原有内容屏蔽,但不要删除):S_Big a;for(int i=0;i200000;+i)TestRef(a);l运行(注意记录大致运行时间)。l将 TestRef 函数的形式参数 x 修改成&xl再次运行程序,记录运行时间。l退出程序,分析两者时间差。2.3实验报告l函数实验的源代码和运行结果分析lnew/delete 实验的源代码和运行结果对比分析l引用实验的源代码和运行结果对比分析面向对象程序设计实验指导书第 5 页实验3 类封装3.1目的和要求l掌握类定义方法,包括数据成员和函数成员的定义方
13、法l掌握对象的创建及其使用l掌握构造函数和析构函数的定义与使用l掌握 this 指针、static 成员和友元的定义与使用l简单的运算符重载函数定义与使用3.2实验内容3.2.1基础定义及函数定义一个 PERSON 类,包括:私有数据成员:姓名指针,年龄,身高,性别,人数(static),外部函数友元一般函数成员:修改与获取数据成员的函数赋值运算符重载成员函数:实现对象赋值构造函数与析构函数:缺省构造函数、一般构造函数、拷贝构造函数、析构函数外部函数:PERSON 对象加法运算符重载函数3.2.2定义要求姓名成员为指针类型。在构造函数中分配相应的空间,在析构函数中释放该空间。采用两种方式定义成
14、员函数(内联方式和非内联方式)加法运算符重载函数为对象和整数相加,更新年龄。赋值运算符成员函数返回当前对象。每个成员函数和加法运算符重载函数均需要输出相应的信息,以确定其调用情况。3.2.3主函数确保每个函数(包括构造函数、析构函数和外部函数)都至少被调用一次。采用不同方式创建对象(静态有名对象和动态无名对象)。每次创建或释放对象之后都应及时输出当前已创建的 PERSON 对象的个数。面向对象程序设计实验指导书第 6 页3.2.4运行程序分析结果给出完整的程序代码、运行结果。每个输出结果产生的原因(代码段)。3.3实验报告l检查以下要求完整性:?类定义?私有成员的数量和要求?函数成员的数量和要
15、求?类内定义成员函数(内联)?类外定义成员函数(非内联)?static 成员?友元?this 指针?外部加法运算符重载函数?创建静态有名对象(调用不同的构造函数)?创建动态无名对象(调用不同的构造函数)?释放动态无名对象?每个函数的输出?构造函数中的动态存储分配和 static 成员的处理?析构函数中的动态存储释放和 static 成员的处理l完整的源程序代码和运行结果l每个运行结果与源程序代码的对应关系l访问对象私有成员所产生的错误信息l创建对象时提供的参数与构造函数不匹配时所产生的错误信息l实验结果分析报告3.4代码样例l下面给出实验 3 的代码样例,以供参考。#include stdaf
16、x.h#include iostream.h#include string.hclass PERSONchar*name;int age;int height;bool gender;面向对象程序设计实验指导书第 7 页static int counter;public:friend PERSON operator+(const PERSON&a,int b);PERSON()name=0;age=0;height=0;counter+;coutPERSON()endl;PERSON(char*n,int a,int h,bool g);PERSON(const PERSON&p);PERSO
17、N operator=(const PERSON&p);PERSON()coutPERSONendl;if(name)delete name;if(counter)counter-;void setname(char*n)coutsetnameendl;if(name)delete name;name=new charstrlen(n)+1;if(name)strcpy(name,n);namestrlen(n)=0;void setage(int a)coutsetageendl;age=a;void setgender(bool g)coutsetgenderendl;gender=g;v
18、oid setheight(int h)coutsetheightendl;height=h;char*getname()coutgetnameendl;if(name)return name;elsereturn NONAME;int getage()coutgetageendl;return age;int getheight()coutgetheightendl;return height;bool getgender()coutgetgenderendl;return gender;static int getcounter()coutgetcounterendl;return cou
19、nter;PERSON:PERSON(char*n,int a,int h,bool g)coutPERSON(char*n,int a,int h,bool g)endl;name=new charstrlen(n)+1;if(name)strcpy(name,n);namestrlen(n)=0;面向对象程序设计实验指导书第 8 页age=a;height=h;gender=g;counter+;PERSON:PERSON(const PERSON&p)coutPERSON(const PERSON&p)endl;if(p.name)name=new charstrlen(p.name)+
20、1;if(name)strcpy(name,p.name);namestrlen(p.name)=0;else name=0;age=p.age;height=p.height;gender=p.gender;counter+;PERSON PERSON:operator=(const PERSON&p)coutoperator=endl;if(name)delete name;if(p.name)name=new charstrlen(p.name)+1;if(name)strcpy(name,p.name);namestrlen(p.name)=0;else name=0;age=p.ag
21、e;height=p.height;gender=p.gender;return*this;PERSON operator+(const PERSON&a,int b)coutoperator+endl;PERSON result;result.age=a.age+b;return result;面向对象程序设计实验指导书第 9 页int PERSON:counter=0;void main()coutcounter:PERSON:getcounter()endl;PERSON a1;coutcounter:PERSON:getcounter()endl;PERSON a2(zhangsan,
22、18,175,true);coutcounter:PERSON:getcounter()endl;PERSON a3=a2;coutcounter:PERSON:getcounter()endl;PERSON a4(a2);coutcounter:PERSON:getcounter()endl;PERSON*p1,*p2,*p3;a1=a2;a1.setname(zhangsi);a1.setage(19);a3.setgender(false);a4.setheight(182);p1=new PERSON;coutcounter:PERSON:getcounter()endl;p2=new
23、 PERSON(Lisi,20,150,false);coutcounter:PERSON:getcounter()endl;p3=new PERSON(*p2);coutcounter:PERSON:getcounter()endl;*p3=*p3+2;*p2=*p1+1;couta1.getname()endl;couta2.getage()endl;couta3.getheight()getgender()coutMaleendl;elsecoutFemaleendl;delete p1;coutcounter:PERSON:getcounter()endl;delete p2;cout
24、counter:PERSON:getcounter()endl;delete p3;coutcounter:PERSON:getcounter()run();CmyApp()delete p;面向对象程序设计实验指导书第 18 页l主函数定义如下例。需要注意到,无论需求如何变化,主函数无需变化。int main(int argc,char*argv)CmyApp Myc;Myc.run();return 0;l作为例子,首先定义一个基本信息类 CBase1,只包括姓名信息和年龄信息:class CBase1:public CBasechar name20;int age;public:CBas
25、e1(char*n,int a)strcpy(name,n);age=a;void run()coutname”,”ageendl;char*getname()return name;int getage()return age;l将应用类中的 XXX 修改成 CBase1(“zhangsan”,18),运行程序观察结果。l随着需求的不断变化,人事管理系统中所需要的个人信息不断增多,此时,不需要修改 CBase1 类的结构,而只需要从 CBase1 类再派生一个新类如下:class CBase2:public CBase1int height;public:CBase2(char*n,int
26、a,int h):CBase1(n,a)height=h;void run()coutgetname()”,”getage()”,”heightendl;int getheight()return height;l再将应用类中的 XXX 修改成 CBase2(“zhangsan”,18,175),而后运行观察结果。l以此类推,该系统适应需求的变化,只需要在原来已有类的基础上派生出一个新类,重写相应的 run()方法,之后再将应用类中的 XXX 及其参数修改成新类的构造函数即可。l而一旦需要需求回退,已有的类不必删除,也只需要将 XXX 改回去即可。l抽象类 CBase 和应用类 CmyApp
27、的存在,在很大程度上简化了为了适应需求的变化而需要进行的代码修改。l实际上,各个类中的 run 方法只是一个接口方法而已。而在具体需求中,可能还会有多种多样的功能设计。这里的 run 方法及其应用形式的思路可以进一步延伸,包括可以设计成插入方法、更新方法、删除方法、查询方法等。但需要注意的原则是,主函数只与应用类相关,而与具体的派生类无关。主函数一旦设计完成,不应该与需求的变化产生依赖关系。可能产生的变化只有应用类 CmyApp,另外就是在已有CBase 类的基础上派生一个新类。10.3.3代码封装及移植l设计思路中描述的 CBase 类和 CmyApp 类是最基本的两个类,可以单独进行封装成
28、面向对象程序设计实验指导书第 19 页一个头文件。l主函数和派生类中的 run 方法定义,是根据控制台应用程序而设计的。如果需要修改成 windows 应用程序,需要进行相应的修改。l主函数也只是作为一个例子而出现。如果将主函数设计成一个应用函数,则可以将该函数作为 DLL 的接口函数形式出现,其中 DLL 中包含了 CBase 类及其派生类和应用类的全集。一旦需求发生变化,则修改该 DLL。10.3.4需求第一步l设计一个人事管理系统l可以管理每个人的姓名、性别和年龄l可插入新资料、删除已有资料l可以根据姓名查询、性别查询和年龄查询l可以根据性别和年龄统计现有人数10.3.5需求第二步l增加人事管理属性:职业和部门l可插入、条件删除、条件更新l根据指定条件统计10.3.6需求第三步l增加人事管理属性:身高、体重、健康状况(良好/一般/差)l可插入、条件删除、条件更新l根据指定条件统计10.3.7需求第四步l身高体重和健康状况管理属性被忽略l回退到第二步的需求10.4实验报告l满足历次需求的程序源代码l操作过程及其运行结果