1、电子科技大学计算机学院标 准 实 验 报 告(实验)课程名称:C+程序设计实验电子科技大学教务处制表电 子 科 技 大 学实 验 报 告学生姓名: 学 号: 指导教师:丘志杰实验地点:主楼A2-412 实验时间:2012.11.23一、实验室名称:电子科技大学计算机实验教学示范中心 二、实验项目名称:C+程序设计实验三、实验学时:学时四、实验原理:了解数据封装的作用和实现方式,使用C+语言的抽象数据类型实现数据封装。了解继承的实现方式,使用C+语言的基类和派生类实现继承功能。了解运算符重载的机制,学会进行运算符重载。了解继承和多态的作用和实现方式,掌握动态联编方法,使用C+语言的抽象类和派生类
2、实现继承性。五、实验目的:1、 掌握C+编程规范;2、 掌握C+的封装、继承、运算符重载以及多态程序的基本编写方法;3、 熟悉在visual Studio 2010(及以上版本)环境下的C+软件开发和调试过程。六、实验内容:C+编辑和编译系统采用isual Studio 2010,设计1个综合运用数据封装、继承、运算符重载、多态等机制的C+编程语言的应用实验“学校教职工工资管理程序”:对学校教职工进行关系划分;着重应用数据封装、继承等机制对各类人员进行类封装并体现继承和派生关系;着重应用虚函数机制,实现计算职工工资的功能;重载“”运算符,能够对对象进行信息输出。七、实验器材(设备、元器件):1
3、硬件平台:【电脑型号戴尔 System Inspiron N4110 笔记本电脑】【处理器英特尔 第二代酷睿 i3-2350M 2.30GHz 双核】速度2.30 GHz (100 MHz x 23.0)处理器数量核心数: 2 / 线程数: 4核心代号Sandy Bridge NB生产工艺32 纳米插槽/插座Socket G2 (PGA 988 / BGA 1023)一级数据缓存2 x 32 KB, 8-Way, 64 byte lines一级代码缓存2 x 32 KB, 8-Way, 64 byte lines二级缓存2 x 256 KB, 8-Way, 64 byte lines三级缓存3
4、 MB, 12-Way, 64 byte lines特征MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, HTT, EM64T, EIST【主板戴尔 03NKW8 (英特尔 HM67 芯片组)】板载设备Intel(R) Extreme Graphics 3 Controller / 视频设备 (启用)板载设备Intel(R) Azalia Audio Device / 音频设备 (启用)BIOS戴尔 Inc. A11制造日期02/09/2012【内存4 GB ( 三星 DDR3 1333MHz )】DIMM 0:三星 DDR3 1333MHz 2GB制造
5、日期2012 年 02 月型号CE M471B5773CHS-CH9序列号:10021220DIMM 2:三星 DDR3 1333MHz 2GB制造日期2011 年 06 月型号CE M471B5773DH0-CH9序列号:0DE93D67【主硬盘西数 WDC WD5000LPVX-22V0TT0 ( 500 GB / 5400 转/分 )】硬盘已使用共 273 次,累计 867 小时固件01.01A01接口SATA III数据传输率600 MB/秒特征S.M.A.R.T, APM, 48-bit LBA, NCQ【显卡ATI Radeon HD 6630M ( 1 GB / 戴尔 )】显卡英
6、特尔 HD Graphics Family显存1803 MB制造商戴尔BIOS日期01/18/20驱动版本9.3.0.0驱动日期20121025主显卡ATI Radeon HD 6630M 显存1 GB制造商戴尔2软件平台:【操作系统Windows 8 专业版 64位 ( DirectX 11 )】系统安装日期Windows 8 / 2013 年 09 月 10 日【开发环境Microsoft Visual Studio Express 2012 for Windows Desktop】版本 11.0.50727.42 VSLRSTAGEMicrosoft .NET Framework版本 4
7、.5.50709已安装的版本: Desktop ExpressTeam Explorer for Visual Studio 2012 05695-004-0030004-02119Microsoft Team Explorer for Visual Studio 2012Visual Basic 2012 05695-004-0030004-02119Microsoft Visual Basic 2012Visual C# 2012 05695-004-0030004-02119Microsoft Visual C# 2012Visual C+ 2012 05695-004-0030004-
8、02119Microsoft Visual C+ 2012NuGet 程序包管理器 2.0.30717.9005SQL Server Data Tools 11.1.20828.01Microsoft SQL Server Data Tools八、实验步骤:1. 了解实验室可用的软硬件开发平台并学习必要的知识,安装并掌握Visual Studio 2010的基本使用方法;2. 设计和编辑学校教职工工资管理程序(1) 对教职工进行人员划分,设计类关系图,设计每个类的成员构成;(2) 在Visual Studio 2010环境下,对各类教职工进行数据封装,并应用继承和派生机制实现类的继承功能;(3
9、) 应用虚函数机制,设计计算职工工资的功能,并在Visual Studio 2010环境下实现该功能;(4) 应用运算符重载机制,在Visual Studio 2010环境下实现对“”运算符的重载,能够对对象进行信息输出。3. 编译和调试(1) 编译相应的C+程序,若不通过,则检查出错原因;(2) 在编译通过的情况下,调试程序,看运行结果是否与预期一致。通过单步或函数级跟进调试程序;4. 美化和优化程序编写规范和结果显示形式5. 截取实验结果图和撰写实验报告九、实验数据及结果分析:1. 实验中采用的默认数据(在程序开始时会显示并且提供了可修改的接口):CAA(A级行政人员提成):100CAB(
10、B级行政人员提成):100CAS(行政人员工龄工资):100CTS(教师工龄工资):100TI1(讲师课时费):10TI2(副教授课时费):20TI3(教授课时费):30TI4(博导课时费):40MS(带研究生提成):50PHD(带博士生提成):1002. 类说明:CSaff:员工基础类,有姓名、工号、工龄、性别、基本工资;CTempStaff:临时工,在员工基础上增加临时工工资;CAdministrator:行政人员,在员工基础上增加“一般、A、B”3个职务等级 其中B级最高;CTeacher:教师,在员工基础上增加“讲师、副教授、教授、博导”4个职务等级,增加“课时、带博士生数、带硕士生数
11、”3方面信息。每个类都重载了函数。所有数据可增加、修改、删除、查询、磁盘读写(默认路径F:staff.txt)。3. 【第一步】初始化测试。实验开始,程序提示正在初始化,自动加载F盘下staff.txt中数据:(类标志、姓名、工号、性别、职务等级、工龄、临时工工资、课时、硕士生数、博士生数)1 meng 2013 M 0 20 1600 200 0 0 03 dsaf 20 F 博导 2 40100 0 200 10 203 fd 213 F 副教授 42 14142 0 20 10 02 sdf 21 F 一般 20 7000 0 0 0 0加载后可根据工号(保证唯一)查询信息。 询问是否需
12、要修改默认数据,选择N,不修改。如附录截图1所示。【第二步】界面测试。程序进入欢迎界面,提供5个选项:1-增加 2-修改 3-删除 4-查询5-存盘退出。如附录截图1所示。【第三步】查询测试。输入4。程序要求输入查询员工的ID,输入2013。程序立即给出了2013工号对应的员工所有信息。如附录截图1所示。【第四步】增加测试。程序自动回到5项选择界面。输入1。提示输入基本信息,根据要求输入了姓名:刘ABC 性别:F 工号:2012050020001 工龄:10 基础工资:2000。提示输入职位:1-临时工 2-行政人员 3-教师,输入了3。提示输入教师职称:1-讲师 2-教授 3-副教授 4-博
13、导,输入了4。提示输入授课时间、所带硕士生数、所带博士生数,输入了200 10 20,程序提示增加成功。如附录截图2所示。【第五步】删除测试。程序自动回到5项选择界面。输入3。提示输入要删除的员工ID,输入2013。程序立即给出了对应工号的员工所有信息,提示是否删除,输入Y。提示删除成功。如附录截图3所示。【第六步】修改测试。程序自动回到5项选择界面。输入2。提示输入要修改的员工ID。输入21。程序立即给出了对应工号的员工所有信息,并且提供了3个选项供修改:1-姓名 2-性别 3-工龄,输入1。提示输入新姓名,输入王三。提示修改成功。如附录截图4所示。【第七步】存盘测试。程序自动回到5项选择界
14、面。输入5。程序自动退出。检查F盘下staff.txt文件可以看到如下数据:3 dsaf 20 F 博导 2 40100 0 200 10 203 刘ABC 2012050020001 F 博导 10 2000 0 200 10 203 fd 213 F 副教授 42 14142 0 20 10 02 王三 21 F 一般 20 7000 0 0 0 0可以看见新增了“刘ABC“员工的信息,删除了”meng”员工的信息,修改了”21“工号员工的姓名,程序测试成功。如附录截图5所示。十、实验结论:程序实现了一个程序实现学校教职工的工资管理,根据相应计算方式设计了类,重载了运算符,并且实现了教职工
15、信息的增加、修改、删除、查询、以及持久化到磁盘中等基本要求。同时,程序还增加了判断,保证了工号的唯一性,优化了数据结构,提升了程序的稳定性、优化了时空复杂度。程序提供了比较好的人机交互界面,用户能根据提示管理整个系统。十一、总结及心得体会:这次实验我学习了很多东西:1. 首先遇到的问题是类的实现。由于不熟练,查询了大量的资料才得以编程,建立了类的继承关系,理清了工资计算方式,实现了封装等操作。2. 重载运算符。由于C+书上没有重载的相关代码,而重载的步骤和普通+-重载不同,极为复杂,需要用到友元类,经过上网查询、请教老师同学、比较完善地重载了运算符。3. Map相关。在考虑采用数据结构存储中,
16、首先想到了数组和普通链表,但是由于数组时间复杂度高,空间无法扩展,普通链表操作难度大,时间复杂度也很高。我考虑了采用STL中的map,map能产生键值对应的关系,而工号正好是满足要求的key。同时,map采用的是一种非常高效的非严格意义上的平衡检索二叉树:红黑树(red-black tree),基本上所有操作都是O(log2n),而且能够自动扩容,提供了大量接口函数,极为方便稳定快捷。因此我采用了map来存储数据。STL操作中遇到了一个有意思的问题:就是释放内存。由于类里面没有数组等数据结构,因此用默认析构函数就好。而map存在深拷贝和浅拷贝的问题。我定义的value是类而不是类指针,因此就是
17、深拷贝,需要释放new出来的对象(原件)。而在最后调用clear()释放map的所有内存时,对象(副本)会去访问它的析构函数,进行内部释放,然后就只剩下raw memory,也就是没有被初始化的内存,它将被归还到alloc里面。如果我定义的是指针的话,clear()就只会释放指针而不会释放指针指向的内容,会产生内存泄漏,因此需要遍历map进行erase和delete来释放内存,比较麻烦。4. 文件操作。文件操作时,我开始使用的是c语言的文件操作语法,由于string这种类类型的特殊性,输入输出的字符串均是乱码。然后我上网查询了一下,知道了要把string加上.c_str变为C语法的字符串才能正
18、常输出。因此干脆就直接用C+的文件操作。在查询大量资料熟悉了C+的文件操作后,成功用流实现了文件的输入输出。其中也遇到了一个问题很有意思:判断文件结尾时如果直接用while(!fin.eof()会产生错误,查询资料后知道因为c+流很特殊,必须要在输入下一个的时候发现没有才会把fin的标志设置为false,fin.eof()才为true,而这样一来就会导致while循环多循环一次产生错误。知道原因也就很方便就能修改对应的代码了。十二、对本实验过程及方法、手段的改进建议: 可以看见的是,没有图形化的界面在输入时需要加大量的判断而浪费时间空间,增加代码难度,因此对错误数据仅仅做了简单的判断处理。如果
19、要实现更健壮的程序,需要加入图形化来处理比较方便。附录: 程序:#include#include#include#include#includeusing namespace std;class CStaff;class CAdministrator;class CTeacher;class CTempStaff;maptpmap;maptcmap;mapadmap;map:iterator tpit;map:iterator tcit;map:iterator adit;int CAA=100,CAB=100,CAS=100,CTS=100,TI1=10,TI2=20,TI3=30,TI4=
20、40,MS=50,PHD=100;/-cstaff-class CStaffprotected:string number;string name;char sex;unsigned int serviceyears;double salary;public:CStaff(string num,string na,char se,unsigned int sy,double sala)number=num;name=na;sex=se;serviceyears=sy;salary=sala;void SetSex(char se) sex=se;char GetSex()return sex;
21、void SetNo(string num)number=num;string GetNo()return number;void SetName(string na)name=na;string GetName()return name;bool SetServiceYears(unsigned int sy)if (sy=0)return false;serviceyears=sy;return true;unsigned int GetServiceYears()return serviceyears;double GetBaseSalary()return salary;virtual
22、 double GetSalary()=0;/-ctempstaff-class CTempStaff:public CStaffprivate:double Ts;public:CTempStaff(string num,string na,char se,unsigned int sy,double sala,double t):CStaff(num,na,se,sy,sala)Ts=t;double GetSalary()return salary+Ts;double GetTs()return Ts;friend ostream&operator(ostream&out ,CTempS
23、taff&obj);ostream&operator (ostream&out ,CTempStaff&obj)out姓名:obj.GetName()endl;if (obj.sex=M)out性别:男endl;else out性别:女endl;out职位:临时工endl;out工号:obj.GetNo()endl;out工龄:obj.GetServiceYears()endl;out薪资:obj.GetSalary()endl;return out;/-cadmin-class CAdministrator:public CStaffprivate:string level;public:C
24、Administrator(string num,string na,char se,unsigned int sy,double sala,string lev):CStaff(num,na,se,sy,sala) level=lev;double GetSalary()if (!pare(一般)return salary+serviceyears*CAS;else if (!pare(A)return salary+serviceyears*CAS+CAA;else if (!pare(B)return salary+serviceyears*CAS+CAB;string Getlevel
25、()return level;friend ostream&operator(ostream&out ,CAdministrator&obj);ostream&operator (ostream&out ,CAdministrator&obj)out姓名:obj.GetName()endl;if (obj.sex=M)out性别:男endl;else out性别:女endl;if (!pare (一般)out职位:一般行政人员endl;else if (!pare (A)out职位:A级行政人员endl;else out职位:B级行政人员endl;out工号:obj.GetNo()endl;o
26、ut工龄:obj.GetServiceYears()endl;out薪资:obj.GetSalary()endl;return out;/-cteacher-class CTeacher:public CStaffprivate:string level;long time,phd,master;public:CTeacher(string num,string na,char se,unsigned int sy,double sala,string lev,long ti,long ph,long ms):CStaff(num,na,se,sy,sala) level=lev;time=t
27、i;phd=ph;master=ms;double GetSalary()if (!pare(讲师)return salary+serviceyears*CTS+time*TI1;else if (!pare(副教授)return salary+serviceyears*CTS+time*TI2+master*MS;else if (!pare(教授)return salary+serviceyears*CTS+time*TI3+master*MS;else if (!pare(博导)return salary+serviceyears*CTS+time*TI4+master*MS+phd*P
28、HD;string Getlevel()return level;long Gettime()return time;long Getphd()return phd;long Getmaster()return master;friend ostream&operator(ostream&out ,CTeacher&obj);ostream&operator (ostream&out ,CTeacher&obj)out姓名:obj.GetName()endl;if (obj.sex=M)out性别:男endl;else out性别:女endl;if (!pare (讲师)out职位:讲师end
29、l;else if (!pare (副教授)out职位:副教授endl;else if (!pare (教授)out职位:教授endl;elseout职位:博导endl;out工号:obj.GetNo()endl;out工龄:obj.GetServiceYears()endl;out薪资:obj.GetSalary()tnum; tpit=tpmap.find (tnum); if (tpit!=tpmap.end() coutendl信息如下:endlsecondendl确认删除?Y/Nyn; if (yn=Y) tpmap.erase(tpit); return true; return
30、false; tcit=tcmap.find(tnum); if (tcit!=tcmap.end() coutendl信息如下:endlsecondendl确认删除?Y/Nyn; if (yn=Y) tcmap.erase(tcit); return true; return false; adit=admap.find(tnum); if (adit!=admap.end() coutendl信息如下:endlsecondendl确认删除?Y/Nyn; if (yn=Y) admap.erase(adit); return true; return false; return false;
31、/-访问函数-bool visitstaff() string tnum; cintnum; tpit=tpmap.find (tnum); if (tpit!=tpmap.end() coutendl信息如下:endlsecondendl; return true; tcit=tcmap.find(tnum); if (tcit!=tcmap.end() coutendl信息如下:endlsecondendl; return true; adit=admap.find(tnum); if (adit!=admap.end() coutendl信息如下:endlsecondendl; retu
32、rn true; return false;/-新增函数-bool newstaff() int op1;string number;string name;char sex;unsigned int serviceyears;double salary;string level;short level2;long time,master=0,phd=0;coutname; coutsex; coutnumber;tpit=tpmap.find (number);tcit=tcmap.find(number);adit=admap.find(number);if (tpit!=tpmap.en
33、d()|tcit!=tcmap.end()|adit!=admap.end()cout此工号已经被占用!endl; return false; coutserviceyears;coutsalary;cout职位:1-临时工 2-行政人员 3-教师op1;switch (op1)case 1:double Ts; coutTs; CTempStaff *c1=new CTempStaff(number,name,sex,serviceyears,salary,Ts); tpmap.insert(pair(c1-GetNo(),*c1); delete c1; return true;case
34、2:coutlevel; CAdministrator *c2=new CAdministrator(number,name,sex,serviceyears,salary,level); admap.insert(pair(c2-GetNo(),*c2); delete c2; return true;case 3:cout教师职称(1-讲师 2-教授 3-副教授 4-博导):level2; switch (level2) case 1:couttime; CTeacher *c3=new CTeacher(number,name,sex,serviceyears,salary,讲师,tim
35、e,phd,master); tcmap.insert(pair(c3-GetNo(),*c3); delete c3; return true; case 2:cout输入授课时间、所带硕士生数,空格间隔,回车结束:timemaster; CTeacher *c4=new CTeacher(number,name,sex,serviceyears,salary,教授,time,phd,master); tcmap.insert(pair(c4-GetNo(),*c4); delete c4; return true; case 3:cout输入授课时间、所带硕士生数,空格间隔,回车结束:ti
36、memaster; CTeacher *c5=new CTeacher(number,name,sex,serviceyears,salary,副教授,time,phd,master); tcmap.insert(pair(c5-GetNo(),*c5); delete c5; return true; case 4:cout输入授课时间、所带硕士生数,所带博士生数,空格间隔,回车结束:timemasterphd; CTeacher *c6=new CTeacher(number,name,sex,serviceyears,salary,博导,time,phd,master); tcmap.i
37、nsert(pair(c6-GetNo(),*c6); delete c6; return true; return false;/-编辑函数-bool editstaff() string tnum;char yn,sex;int op,serviceyears,op1;string name,number;cintnum;tpit=tpmap.find (tnum);tcit=tcmap.find(tnum);adit=admap.find(tnum);if (tpit!=tpmap.end()op1=1; coutendl信息如下:endlsecondendl;else if (tcit!=tcmap.end()op1=2;coutendl信息如下:endlsecondendl;else if (adit!=admap.end()op1=3;coutendl信息如下:endlsecondendl;else return false;if (tpit!=tpmap.end()|tcit!=tcmap.end()|adit!=admap.end()cout输入要修改的项目:1-姓名 2-性别 3-工龄endl