天津理工大学C++期末考试_第1页
天津理工大学C++期末考试_第2页
天津理工大学C++期末考试_第3页
天津理工大学C++期末考试_第4页
天津理工大学C++期末考试_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验一明确的概念:〔1〕理解类和对象的概念;〔具体见附一〕类是抽象的对象是具体的例如:你、我、他都是人那么你、我、他就是对象人就是类〔2〕掌握类与对象的定义方法;类的定义:class类名{…/*定义这个类*/};//(别忘了最后的分号)对象的定义:类名对象名(参数);〔3〕理解类的成员的访问控制的含义,公有和私有成员的区别; public://访问属性为公有通过外部直接访问即: private://访问属性为私有不能通过外部直接访问〔不声明访问属性时系统默认为私有〕当出现对象名.成员(私有)时编译器报错 protected://访问属性为保护与private类似但protected属性的成员可以继承private不能继承〔4〕掌握构造函数和析构函数的含义与作用、定义方式和实现; 构造函数:为数据成员开辟存储空间 函数名必须与类名相同之前绝对不许说明返回值类型void也不行 构造函数不能由用户调用即:对象名.构造函数名(参数)是错误的 构造函数是随着对象的声明而调用的 例如: classStudent{Student(){cout<<〞Hello.〞<<endl;}};Intmain(void){cout<<〞Hello.〞<<endl;StudentA;}运行结果: Hello. //<-这个Hello是主函数中的 Hello. //<-是声明A对象时调用的构造函数构造函数中的Hello 析构函数功能与构造函数相反注意调用时间和顺序(看书)附:如何知道该程序析构函数的调用顺序是p3p2p1?答:将拷贝构造函数中改为x=附:如何知道该程序析构函数的调用顺序是p3p2p1?答:将拷贝构造函数中改为x=2*p.x;y=2*析构函数中在cout<<〞Destructoriscalled.〞之后添加<<〞x=〞<<x<<〞y=〞<<y后面的不变运行时析构函数输出结果变为:Destructoriscalled.x=12y=16Destructoriscalled.x=6y=8Destructoriscalled.x=3y=4Pressanykeytocontinue由此可知其调用顺序或者在拷贝构造函数和析构函数中的cout语句的<<endl;之前参加<<this来输出对象地址再对号入座也可知调运顺序输入以下程序,按要求进行实验,并记录实验的结果。#include<iostream>usingnamespacestd;classCoordinate{public: Coordinate(intx1,inty1){x=x1;y=y1;} Coordinate(Coordinate&p); ~Coordinate(){cout<<"Destructoriscalled."<<endl;} intgetx(){returnx;} intgety(){returny;}private: intx,y;};Coordinate::Coordinate(Coordinate&p){//拷贝构造函数 x=p.x;y=p.y; cout<<"Copyinitianizationconstructoriscalled."<<endl;运行结果:Copyinitianizationconstructoriscalled.运行结果:Copyinitianizationconstructoriscalled.Copyinitianizationconstructoriscalled.p3=(3,4)Destructoriscalled.Destructoriscalled.Destructoriscalled.Pressanykeytocontinue调用构造函数调用拷贝构造函数〔见书P89〕调用构造函数调用拷贝构造函数〔见书P89〕 Coordinatep1(3,4); Coordinatep2(p1); Coordinatep3=p2; cout<<"p3=("<<p3.getx()<<","<<p3.gety()<<")"<<endl;程序结束时调用析构函数注意析构函数的调用顺序从上至下依此为p3p2p1的析构函数程序结束时调用析构函数注意析构函数的调用顺序从上至下依此为p3p2p1的析构函数 return0;}记录程序的运行结果将Coordinate类中带有两个参数的构造函数进行修改,在函数体内增加如下语句:cout<<〞Constructoriscalled.〞<<endl; 重新记录程序的运行结果,并解释输出结果。按以下要求进行测试。在主函数体内,添加如下语句:Coordinatep4; 错误原因:构造函数没有参数构造函数为Coordinate::Coordinate(int,int)Coordinatep5(2); 错误原因:参数数量不对根据注释语句的提示实现类Date的成员函数,并将完整的程序编译、连接成功以保证程序能够正确运行。#include<iostream.h>classDate{public: voidprintDate(); //显示日期分析:1.题目中Date类的数据成员为day,month,year且均为整型访问属性为私有主函数中声明了testDay对象2.数据成员均为私有那么不能通过tesDay.day=<数值>的方法来设置题目中给出了voidsetDay(int)voidsetMonth(int)和voidsetYear(int)三个成员函数去是指daymonth和year的值还有一个voidprintDate()来输出分析:1.题目中Date类的数据成员为day,month,year且均为整型访问属性为私有主函数中声明了testDay对象2.数据成员均为私有那么不能通过tesDay.day=<数值>的方法来设置题目中给出了voidsetDay(int)voidsetMonth(int)和voidsetYear(int)三个成员函数去是指daymonth和year的值还有一个voidprintDate()来输出3.准备工作结束开始编程看程序仅差4个成员函数未定义类外定义要写出作用域即该函数属于哪个类:格式:返回值类型作用域::函数名参数表voidDate::setDay(intd)/*定义时必须要给形参一个名字这里给的是*/d{day=d}//设置了day的值其他函数依此类推输出函数就不用再唠叨了4.验证结果出现溢出数据时查看是否写反了例如写成d=day了解设置函数的作用机制见附二 voidsetMonth(int);//设置月的值 voidsetYear(int);//设置年的值private: intday,month,year;};intmain(){ DatetestDay; testDay.setDay(5); testDay.setMonth(10); testDay.setYear(2023); testDay.printDate();};voidDate::setDay(intd){day=d;}voidDate::setMonth(intm){month=m;}voidDate::setYear(inty){year=y;}voidDate::printDate(){cout<<year<<"/"<<month<<"/"<<day<<endl;}3. 下面是一个计算器类的定义,请完成该类的成员函数的实现,并设计一个主函数使用该类和相关成员函数以测试该类设计的正确性。#include<iostream>usingnamespacestd;classcounter{public: counter(intnumber=0) //构造函数 { value=number; }voidincrement(); //给value原值加1 voiddecrement(); //给value原值减1 intgetvalue(); //取得计数器值 intprint(); //显示计数private: intvalue; //数据成员};voidcounter::increment(){value++;cout<<"Thecounterhasincreasedby1"<<endl;}//〔其中的cout语句可以不写〕voidcounter::decrement(){value--;cout<<"Thecounterhasdecreasedby1"<<endl;}intcounter::getvalue(){returnvalue;}intcounter::print(){cout<<"\nDisplay:"<<getvalue()<<endl<<endl;return0;}intmain(){ cout<<"Pleaseinputoriginnumber:"; //定义counter类的几个对象并调用有关成员函数 inta; cin>>a; counterc(a);//输入a并将a作为参数通过构造函数为对象中的value赋值 c.increment(); c.print(); //题目要求验证所以使用输出函数一次验证value的值 c.decrement(); c.print(); return0; }4.定义一个类ClsName,要求该类设计如下:〔1〕该类有两个整型数据成员x和y;〔2〕为该类重载三个不同的构造函数:分别为无参数、带一个参数和带两个参数的构造函数,要求在构造函数中输出必要的信息以示区别;〔3〕设计2个成员函数用来读取数据成员x和y;〔4〕设计2个成员函数用来设置数据成员x和y;〔5〕设计1个成员函数用来在屏幕上打印输出数据成员x和y;〔6〕在main〔〕函数中用三个不同的构造函数创立3个对象,并使用所有的成员函数对这些对象进行必要的操作。classClsName{public: inta,b; ClsName(inta,intb){cout<<"Constructbytwonumbers."<<endl;x=a,y=b;} //以下三个(2)中要求的重载构造函数 ClsName(inta){cout<<"Constructby1number."<<endl;x=a,y=b;}//题目要求加以区别,所以cout输出不同内容加以区分 ClsName(void){cout<<"Constructwithoutanumber."<<endl;x=a,y=b;} intgetx(){returnx;}因为x,y的访问属性为私有,不能由主函数直接访问所以会设置读取函数专门负责返回相应的值重载:函数名相同,参数的类型不同或者个数不同、或者都不同。即根据带入参数的类型、数量的不同,来实现不同的功能 intgety(){returny;}重载:函数名相同,参数的类型不同或者个数不同、或者都不同。即根据带入参数的类型、数量的不同,来实现不同的功能 voidsetx(){cout<<"ChangeX:";cin>>x;} voidsety(){cout<<"ChangeY:";cin>>y;} voidprint(){cout<<"X="<<getx()<<'\t'<<"Y="<<gety()<<endl;}private: intx,y;〔1〕中要求的两个整型数据成员};intmain(){ inta,b; cout<<"Test1:Inputwith2numbers,nowpleaseinputtwonumbers:"<<endl; cin>>a;cin>>b; ClsNamet1(a,b); t1.print(); t1.setx();t1.sety(); t1.print(); cout<<"\nTest2:Inputwithanumbers,nowpleaseinputanumber:"; cin>>a; ClsNamet2(a); t2.print(); t2.setx();t2.sety(); t2.print(); cout<<"\nTest3:Withoutnumbers"; ClsNamet3; t3.print(); t3.setx();t3.sety(); t3.print(); return0;5. 建立类cylinder,包括两个数据成员radius和height,分别表示圆柱体的半径和高度,cylinder类的构造函数被传递了两个double值来初始化这两个成员;定义成员函数area()和volume用来求圆柱体的外表积和体积,定义成员函数print()打印cylinder类的相关信息。最后,在主函数中对cylinder类的设计进行测试。这题很简单没啥说的#include<iostream.h>classcylinder{public: voidset(doubler,doubleh){radius=r,height=h;} doublearea(){return(radius*3.14);} doublevolume(){return(height*area());} voidprint(){cout<<"Area="<<area()<<'\t'<<"Volume="<<volume()<<endl;}private: doubleradius,height;};intmain(){ inta,b; cylinderv; cout<<"Radius="; cin>>a; cout<<"Height="; cin>>b; v.set(a,b); v.print(); return0;}6.定义一个学生类CStudent实现简单的学籍管理功能,要求该类至少实现以下功能:(1)录入学生的根本信息(包括姓名,学号,性别,年龄,专业,入学时间,各门功课成绩)(2)输出学生的根本信息(3)选课〔输入时间和所选的课程〕(4)统计每门课的学分绩点(5)统计每学期的平均学分绩点(6)统计重考科目(7)统计重修科目#include<iostream>#include<string>usingnamespacestd;constMAX=4;classCStudent{ stringname,sex,ID,object,jtime;//分别存储姓名性别学号专业入学时间 intage; //存储年龄 intmark[MAX]; //设立一个数组存放成绩 stringsbj[MAX]; //设立string数组来存放科目名称 intretry,redo; //统计重考重修数量 stringt_chose,s_chose; //存放选课时间和选课名称 intm_point[MAX],m_mark[MAX]; //存放每门功课的学分和绩点 intmarker[MAX]; //存放重修科目的角标〔有时不止挂掉一科可能会很多所以声明称数组〕为什么建立数据时使用的数组?通过对角标的控制便可以把一行数据全部对应起来为什么建立数据时使用的数组?通过对角标的控制便可以把一行数据全部对应起来请看下面数据对应关系:角标科目名称(sbj[i])成绩(mark[i])学分(m_mark[i])0数学4461C语言9262英语724便于统计也可以方便地调用出一门科目的全部内容public: CStudent() { cout<<"构造CStudent开始录入根本信息"<<endl; cout<<"Name:";cin>>name; cout<<"ID:";cin>>ID; cout<<"Sex:";cin>>sex; cout<<"Age:";cin>>age; cout<<"YourObject:";cin>>object; cout<<"Timeyoujointhecolleage:";cin>>jtime; cout<<"Nowpleaseinputyourmarks."<<endl; for(inti=0;i<MAX;i++) { cout<<"Subjectname:";cin>>sbj[i]; cout<<"Mark:";cin>>mark[i]; } } voidbaseprint() //按(2)要求输出根本信息 { cout<<"根本信息:"<<endl; cout<<"学生姓名:"<<name<<"\t学号:"<<ID<<"\t年龄:"<<age<<"\t性别"<<sex<<endl; cout<<"入学时间:"<<jtime<<"\t专业:"<<object<<endl; cout<<"成绩:"<<endl; for(inti=0;i<MAX;i++) { cout<<sbj[i]<<":"<<mark[i]<<"\t"; } cout<<endl; } voidchose() //按(3)要求设置选课函数 { cout<<"选课名称:";cin>>s_chose; cout<<"选课时间:";cin>>t_chose; } voidPoint() //按(4)要求 { for(inti=0;i<MAX;i++) { cout<<"请设置"<<sbj[i]<<"的学分:";cin>>m_mark[i]; } cout<<endl; cout<<endl; intscore=0,j=0; //给score赋初值防止溢出因为后面有score+=...相当于score=score+...无法确定第一个score的值 retry=0; for(i=0;i<MAX;i++) { if(mark[i]>=60)score+=m_mark[i]; //成绩及格垒加学分 else{retry++;marker[j++]=i;} //否那么不及格便要重考将重考数量自增 } //其中marker[j++]=i是将当时重修科目的角标记录下来 floats=0; for(i=0;i<MAX;i++){ if(m_mark==0){m_point[i]=0;cout<<sbj[i]<<"学分绩点均为0"<<endl;continue;} float(m_point[i]=4-(100-(float)mark[i])*(100-(float)mark[i])/1600);//绩点的计算方法 s+=m_point[i]; cout<<sbj[i]<<"所获学分:"<<m_mark[i]<<"\t绩点:"<<m_point[i]<<endl; } cout<<"平均绩点为:"<<s/MAX<<endl; cout<<endl; } voidcheck() { if(retry==0)cout<<"无重考科目"; else { cout<<"重考数目为:"<<retry<<"包括"<<endl; for(inti=0;i<retry;i++)cout<<sbj[marker[i]]<<"\t"; cout<<endl; redo=0; cout<<endl; inttemp,j=0; cout<<"输入重考分数"<<endl; for(i=0;i<retry;i++) { cout<<sbj[marker[i]]<<":";cin>>temp; if(temp<60) { redo++; marker2[j++]=marker[i]; } } cout<<endl; if(redo==0)cout<<"无重修科目"; else { cout<<"重修数目为:"<<redo<<"包括"<<endl; for(i=0;i<redo;i++)cout<<sbj[marker2[i]]<<"\t"; cout<<endl; } } }};intmain(void){ CStudenta; a.baseprint(); a.chose(); a.Point(); a.check(); return0;}注意:〔1〕新设计的类中所需要的数据成员需要根据所要实现的功能自行设计;〔2〕用一个演示程序完成对所设计的新类的功能测试,并给出测试数据和实验结果;〔3〕为增加程序可读性,请在程序中对类成员进行适当注释说明;补充实验题: 〔1〕教材134页【3.33】-【3.36】实验二〔2010-3-23〕实验名称:复杂形式的对象。实验目的:〔1〕掌握对象数组、对象指针和string类的使用方法; 把对象想象成一种数据类型比方整型有整型数组吧〔inta[10]〕自然也有对象数组 对象指针以以上类似有时涉及到动态联编〔〕String类不如说是string类型类似于智能化的字符串数组〔2〕掌握对象数组、对象指针和对象引用作为函数参数的使用方法; 主要看书实际用的不多注意对象数组初始化方法〔书P77中上的说明〕〔3〕掌握类对象作为成员的使用方法; 了解就行〔4〕掌握友元的概念和使用方法; 通常的,通过A对象想要访问B对象的私有成员是不可能的而通过友元就可以做到 需要注意的是友元函数虽然在类内声明但是友元函数不是成员函数独立于类外所以类外定义是不能加作用域“::〞 另外,由于使用的VisualC++6.0不是完全使用C++标准编程时如果遇到报错内容为一堆大写字母且错误位置指向友元函数的话把#include<iostream>usingnamespacestd;改为#include<iostream.h>还有!只有上述情况才可以把头文件加上“.h〞,否那么会导致局部功能不正常〔5〕掌握静态数据成员和静态成员函数的使用方法; 例如:有Object类,拥有数据成员a,由Object类声明出的对象A、B、C,那么A、B、C都拥有各自的a,内存中也会分配出各自的内存空间A::a,B::a,C::a〔共3个〕。而如果将数据成员a声明为静态成员〔static〕,那么A、B、C那么共用一个内存空间a〔只有1个〕最典型的例子是统计声明对象的数量使用方法:static数据类型数据成员名由于不能直接对数据成员赋初值所以静态数据成员初始化方法为:数据类型类名::静态数据成员名=初值〔注意:1.是类名,不是对象名;2.之前不要加static〕静态成员函数静态成员函数属于整个类而不是某个对象所以调用方法为类名::静态成员函数名(参数表)其他参看书P103几点说明练习工程Time类的框架定义如下:#include<iostream.h>classTime //声明Time类{public: Time(intA=0,intB=0,intC=0)//带默认参数的构造函数 { hour=A; minute=B; second=C; } //setfunctions voidsetTime(inta,intb,intc) //设置hour,minute,second { cout<<"RunSetimeFunction"<<endl; setHour(a); setMinute(b); setSecond(c); }voidsetHour(inta)//设置hour(确保数据在合理范围) { for(;;) { if(a>=24||a<0) { cout<<"小时输入错误再来一次"<<endl; cin>>a; } else{break;} } hour=a; }voidsetMinute(inta) //设置minute(确保数据在合理范围) { for(;;) { if(a>=60||a<0) { cout<<"\n分钟输入错误再来一次"<<endl; cin>>a; } else{break;} } minute=a; }voidsetSecond(inta) //设置second(确保数据在合理范围) { for(;;) { if(a>=60||a<0) { cout<<"秒输入错误再来一次"<<endl; cin>>a; } else {break;} } second=a; }//getfunctionsintgetHour()//返回hour { returnhour; }intgetMinute()//返回minute { returnminute; }intgetSecond()//返回second { returnsecond; }voidprintUniversal()//按24小时格式输出时间:23:56:12 { cout<<getHour()<<":"<<getMinute()<<":"<<getSecond()<<endl; } voidprintStandard()//按12小时格式输出时间:11:56:12(PM)或9:23:55(AM) {if(hour>12) cout<<(hour-12)<<":"<<minute<<":"<<second<<"(PM)"<<endl; else cout<<hour<<":"<<minute<<":"<<second<<"(AM)"<<endl; }private: inthour; //0-23(24小时格式) intminute;//0-59 intsecond;//0-59};//Timel类定义结束intmain(){ Timet; inta,b,c; cout<<"设置小时:"; cin>>a; cout<<"设置分钟:"; cin>>b; cout<<"设置秒:"; cin>>c; t.setTime(a,b,c); t.printStandard(); t.printUniversal(); return0;2.设计一个用来表示直角坐标系的Location类,在主程序中创立类Location的两个对象A和B,要求A的坐标在第3象限,B的坐标点在第2象限,分别采用成员函数和友元函数计算给定两个坐标点之间的距离,要求按如下格式输出结果:A〔x1,y1〕,B〔x2,y2〕Distance1=d1Distance2=d2其中:x1,x2,y1,y2为指定的坐标值,d1和d2为两个坐标点之间的距离。Location类框架可参考如下:#include<iostream.h>#include<cmath>classLocation //声明类Location{public: Location(double,double); //构造函数 doubleGetx(); //成员函数,取x坐标的值 doubleGety(); //成员函数,取y坐标的值 doubledistance1(Location&);//成员函数,求两坐标点之间的距离frienddoubledistance2(Location&A,Location&B)//友元函数,求两坐标点之间的距离 { returnsqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); }~Location(void){cout<<"Destrcted..";}private: doublex,y;};Location::Location(doublea,doubleb){ x=a; y=b;}doubleLocation::Getx(){ returnx;}doubleLocation::Gety(){ returny;}doubleLocation::distance1(Location&L){ returnsqrt((L.x-x)*(L.x-x)+(L.y-y)*(L.y-y));}intmain(){ doublea,b; cout<<"输入A点坐标〔在第二象限〕:"<<endl; cout<<"x(x<0):"; for(;;) { cin>>a; if(a<0)break; cout<<"不对,再来一次:"; } cout<<"y(y>0):"; for(;;) { cin>>b; if(b>0)break; cout<<"不对,再来一次:"; } LocationA(a,b); cout<<"输入B点坐标〔在第四象限〕:"<<endl; cout<<"x(x>0):"; for(;;) { cin>>a; if(a>0)break; cout<<"不对,再来一次:"; } cout<<"y(y<0):"; for(;;) { cin>>b; if(b<0)break; cout<<"不对,再来一次:"; } LocationB(a,b); cout<<"A("<<A.Getx()<<","<<A.Gety()<<")"<<endl; cout<<"B("<<B.Getx()<<","<<B.Gety()<<")"<<endl;1(B)<<endl; cout<<"Distance2="<<distance2(A,B)<<endl; return0;}3.使用C++的string类,将5个字符串按逆转后的顺序显示出来。例如,逆转前的5个字符串是:Germany逆转后的顺序输出字符串是:France#include<iostream>#include<string>usingnamespacestd;intmain(void){ stringstr1,str2,str3,str4,str5; cin>>str1>>str2>>str3>>str4>>str5; cout<<str5<<""<<str4<<""<<str3<<""<<str2<<""<<str1<<endl; return0;}4.设计一个模仿类magic来实现4*4的魔方阵。类的框架如下:#include<iostream>usingnamespacestd;classmagic //声明魔方阵类magic{public: voidgetdata(); //输入初值成员函数 voidsetfirstmagic(); //设置初始魔方成员函数 intgenerate(); //生成最终魔方成员函数 intprintmagic(); //显示魔方成员函数private: intm[4][4]; intstep; intfirst; intsumj;};voidmagic::getdata(){ cout<<"first=";cin>>first; cout<<"step=";cin>>step;}voidmagic::setfirstmagic(){ inttemp; temp=m[0][0]=first; for(inti=0,j=0;i<4;i++) for(j=0;j<4;j++) { if(i==0&&j==0)continue; temp+=step; m[i][j]=temp; } sumj=m[0][0]+m[3][3];}intmagic::generate(){ inti,j; for(i=0,j=3;i<4;i++,j--) { m[i][j]=sumj-m[i][j]; m[i][i]=sumj-m[i][i]; } return0;}intmagic::printmagic(){ cout<<endl; for(inti=0,j;i<4;i++) { for(j=0;j<4;j++) cout<<m[i][j]<<"\t"; cout<<endl; } return0;} intmain(void){ magicm; m.getdata(); m.setfirstmagic(); m.generate(); m.printmagic(); return0;}所谓4*4的魔方阵,是指该矩阵的各行值的和等于各列值的和,并等于两对角线值的和,如:,其各行、各列以及对角线值的和都是64。求4*4的魔方阵的一般步骤提示如下:设置初始魔方的起始值和相邻元素之间的差值。例如上述魔方阵的初始魔方的起始值和相邻元素之间的差值分别为:first=1,step=2设置初始魔方元素的值。例如上述魔方的初始魔方阵为:生成最终魔方阵。方法如下:eq\o\ac(○,1)求最大元素和最小元素的和sum,本例为1+31=32。eq\o\ac(○,2)用32减去初始魔方阵所有对角线上元素的值,然后将结果放在原来的位置,即可求得最终的魔方阵。本例最终魔方阵为:编写主程序,测试所设计的魔方类的正确性.5.声明一个Employee类,数据成员包括:一个long型的id,两个字符指针成员,代表职员的姓名和家庭住址,一个double数据,代表月薪。成员函数有:构造函数、析构函数、set_salary()和get_salary()代表修改和获取薪资、set_name()和get_name()代表修改和获取姓名、set_address()和get_address()代表修改和获取家庭住址,set_id()和get_id()用来修改获取当前职员的id号。在主程序中,创立对象数组调用上述函数以测试Employee类设计的正确性。Employee类的框架可参考:#include<iostream>#include<string>usingnamespacestd;classEmployee //声明Employee类{public: Employee(long=0,char*="000",char*="000",double=0);//构造函数 ~Employee(); //析构函数 //setfunctions voidset_id(long); //设置id voidset_salary(double); //设置salaryvoidset_name(char*); //设置namevoidset_address(char*); //设置adress//getfunctions longget_id(); //返回iddoubleget_salary(); //返回salarychar*get_name(); //返回namechar*get_addressSecond(); //返回addressvoidprint(); //打印输出Employee的相关信息private:longid; //工号char*name; //姓名char*address; //家庭住址doublesalary; //月薪};//Employee类声明结束Employee::Employee(long,char*,char*,double){ name=newchar; address=newchar;}voidEmployee::set_address(char*q){ address=q;}voidEmployee::set_id(longa){ id=a;}voidEmployee::set_name(char*z){ name=z;}voidEmployee::set_salary(doublea){ salary=a;}longEmployee::get_id(){ returnid;}doubleEmployee::get_salary(){ returnsalary;}char*Employee::get_name(){ returnname;}char*Employee::get_addressSecond() //返回address{ returnaddress;}Employee::~Employee(){}voidEmployee::print(){ cout<<"======================================================="<<endl; cout<<"\tID"<<get_id()<<"\t\t"<<"姓名::"<<get_name()<<"\n\t月薪:"<<get_salary()<<endl; cout<<"\t住址:"<<get_addressSecond()<<endl;}intmain(void){ cout<<"输入要统计的员工数量:"; inti;cin>>i; intj=0,a; doubleb; cout<<"\n\n\n\t\t\t\t===录入信息==="<<endl; Employees[1000]; char*p; for(;j<i;j++) { cout<<"\n输入员工ID:"; cin>>a; s[j].set_id(a); p=newchar[1000]; cout<<"员工姓名:";cin>>p; s[j].set_name(p); p=newchar[1000]; cout<<"员工住址:";cin>>p; s[j].set_address(p); cout<<"输入员工工资:"; cin>>b; s[j].set_salary(b); } for(j=0;j<i;j++) s[j].print(); return0;}6.声明一个Student类,在该类中包括一个数据成员:score〔代表课程成绩〕、两个静态数据成员:total_score〔代表总分〕,count〔代表学生总人数〕。成员函数有:构造函数、析构函数、account〔int〕用于设置分数、静态成员函数sum()返回所有学生的总成绩、静态成员函数average()返回所有学生的平均成绩、print()用于打印当前学生对象的成绩等。在主程序中,输入某班同学的成绩,并调用上述函数打印全班同学的成绩、求出全班学生的成绩之和与平均分等。Student类的框架可参考:#include<iostream>#include<string>usingnamespacestd;classStudent //声明Student类{public: Student(int=0); //构造函数 ~Student(); //析构函数 voidaccount(int); //设置分数 staticintsum(); //返回总成绩 staticdoubleaverage();//返回平均成绩 voidprint2(); // 打印输出Student的平均成绩和总成绩voidprint(); // 打印输出Student的相关信息private:intscore; //分staticinttotal_score; //总分staticintcount; //人数};//Student类声Student::Student(int){ score=0;}Student::~Student(){}voidStudent::account(inta){ score=a; total_score+=score; count++;}intStudent::sum(){ returnStudent::total_score;}doubleStudent::average(){ returnStudent::total_score/double(Student::count);}voidStudent::print(){ cout<<score<<"\t";}voidStudent::print2(){ cout<<"\n全班统计:\n总成绩:"<<Student::sum()<<"\n平均成绩:"<<Student::average()<<endl;}intStudent::count=0;intStudent::total_score=0;intmain(void){ inti=0,a; Students[100]; cout<<"开始录入成绩,输入-1结束"<<endl; while(i>=0) { cin>>a; if(a<0) { cout<<"成绩录入结束"<<endl;break; } s[i++].account(a); } cout<<"输出全班成绩:"<<endl; intj=1; while(i>0) { s[--i].print(); if(j++%6==0)cout<<endl; } s[0].print2(); return0;}注意:静态成员和非静态成员的初始化方式的区别。实验三派生与继承〔2010-3-23〕实验名称:派生与继承。实验目的:理解继承的含义,掌握派生类的定义方法和实现;继承就是子承父类看书注意格式私有成员不能继承父类的保护成员继承成变为子类的私有成员理解公有继承下基类成员对派生类成员和派生类对象的可见性,能正确地访问继承层次中的各种类成员;理解保护成员在继承中的作用,能够在适当的时候选择使用保护成员以便派生类成员可以访问基类的局部非公开的成员;理解虚函数在类的继承层次中的作用,虚函数的引入对程序运行时的影响,能够对使用虚函数的简单程序写出程序结果。练习工程“点〞类Point,再由“点〞类派生出“圆〞类Circle。#include<iostream.h>classPoint//定义“点〞类{ intx,y;public: Point(inta=0,intb=0) { x=a;y=b; } voidShowPoint() { cout<<"Point:("<<x<<','<<y<<")\n"; } intGetx() { returnx;} intGety() { returny; } voidSetxy(inta,intb) { x=a;y=b; }};classCircle:publicPoint//定义“圆〞类,公有继承{ intr;//“圆〞的半径public: Circle(intx,inty,intra):Point(x,y)//B { r=ra; } voidSetr(intra) { r=ra;} doubleArea()//求圆的面积 { returnPI*r*r; } voidMove(intx_offset,inty_offset)//将圆心坐标平移 { intx1=Getx();//存取基类的私有成员 inty1=Gety();//D x1+=x_offset;y1+=y_offset;Setxy(x1,y1);//E } voidShowCircle() { ShowPoint();//F cout<<"Radius:"<<r<<'\t'; cout<<"Area:"<<Area()<<endl;//G }};voidmain(){ Circlec(1,1,1); c.ShowCircle(); c.Move(1,2); c.ShowCircle();c.Setxy(4,5);//重新置圆心坐标 c.Setr(2);//重新置半径值 c.ShowCircle();}记录程序的运行结果测试能否将move函数体改写为x=x+x_offset;y=y+y_offset; 运行结果略1(2)不能改写派生类不能直接访问基类的私有成员2:先定义“点〞类Point和“半径〞类Radius,再由Point类和Radius类多重派生出“圆〞类Circle。#include<iostream.h>classPoint{protected://A intx,y;public: Point(inta=0,intb=0){x=a;y=b;} voidShowPoint(){cout<<"Point:("<<x<<','<<y<<")\n";} intGetx(){returnx;} intGety(){returny;} voidSetxy(inta,intb){x=a;y=b;}};classRadius{protected://B intr;public: Radius(intra=0){r=ra;} voidSetr(intra){r=ra;} intGetr() {returnr;}};classCircle:publicPoint,publicRadius{public: Circle(intx,inty,intra):Point(x,y),Radius(ra)//D {}doubleArea() {returnPI*r*r;}//直接访问基类的保护成员voidMove(intx_offset,inty_offset) {x+=x_offset;y+=y_offset;}voidShowCircle() { ShowPoint(); cout<<"Radius:"<<r<<'\t'; cout<<"Area:"<<Area()<<endl; }};voidmain(){ Circlec(1,1,1); c.ShowCircle(); c.Move(1,2); c.ShowCircle(); c.Setxy(4,5); c.Setr(2); c.ShowCircle();}记录程序的运行结果运行结果略为什么可以直接使用x,y,基类的数据成员x,y为保护数据成员相当于派生类的私有数据成员可以被派生类的成员函数访问如果x,y在基类中是私有的行吗?私有那么不能被访问3.多重继承中基类构造函数和析构函数的调用顺序#include<iostream.h>classBase1{protected: intdata1;public: Base1(inta=0) { data1=a; cout<<"BaseConstructor1\n"; } ~Base1() { cout<<"BaseDestructor1\n";}};classBase2{protected: intdata2;public: Base2(inta=0) { data2=a; cout<<"BaseConstructor2\n"; } ~Base2() { cout<<"BaseDestructor2\n";}};classDerived:publicBase1,publicBase2{ intd;public: Derived(intx,inty,intz):Base1(x),Base2(y) {d=z; cout<<"DerivedConstructor\n"; } ~Derived() {cout<<"DerivedDestructor\n";} voidShow() {cout<<data1<<','<<data2<<','<<d<<endl;}};voidmain(){ Derivedc(1,2,3); c.Show();}记录程序的运行结果运行结果:BaseConstructor1BaseConstructor2DerivedConstructor1,2,3DerivedDestructorBaseDestructor2BaseDestructor1Pressanykeytocontinue要求记住调用顺序#include<iostream.h>classBase1{protected: intdata1;public: Base1(inta=8){ data1=a; cout<<data1<<",BaseConstructor1\n"; } ~Base1() { cout<<data1<<",BaseDestructor1\n"; }};classBase2{protected:intdata2;public: Base2(inta=9) { data2=a; cout<<data2<<",BaseConstructor2\n"; } ~Base2() { cout<<data2<<",BaseDestructor2\n"; }};classDerived:publicBase1,publicBase2{ intd; Base1b1,b2;public:Derived(intx,inty,intz):Base1(x),Base2(y),b1(x+y),b2(x+z) { d=z;cout<<"DerivedConstructor\n"; } ~Derived() { cout<<"DerivedDestructor\n"; } voidShow() { cout<<data1<<','<<data2<<','<<d<<endl; }};voidmain(){ Derivedc(1,2,3); c.Show();}记录程序的运行结果1,BaseConstructor12,BaseConstructor23,BaseConstructor14,BaseConstructor1DerivedConstructor1,2,3DerivedDestructor4,BaseDestructor13,BaseDestructor12,BaseDestructor21,BaseDestructor1Pressanykeytocontinue5.编程题假设某商店有如下几种货品:衬衣、帽子、立柜。每一种货物都有与其关联的说明信息。衬衣:单价、产地、库存量、布料;帽子:单价、产地、库存量、布料、样式〔平顶或尖顶〕;立柜:单价、产地、库存量、木料、颜色。对这些商品的操作有:商品的进库〔增加库存量〕,商品的出库〔减少库存量〕,该类货品总价格的计算。要求自行设计数据结构,用类的继承与派生关系将上述的各种货品表示出来,并使用类的构造函数来初始化每一类对象的初始数据。而后将上述的商品管理计算机化,完成操作要求的功能。【实现方法提示】1.设立3个不同的类来描述与处理3种不同的货品。首先注意到上述3种货品数据之间的相互关联关系,可使用C++基类及其派生类的定义方法,先抽象出〔“提取〞出〕如下每一货品都具有的“公有〞数据构成一个所谓的基类base,而后再派生出所需的那3个类。〔1〕base〔基〕类:单价、产地、库存量;〔2〕由base作为基类,派生出shirt〔衬衣〕类:增加“布料〞数据;〔3〕由base出发,派生出wardrobe〔立柜〕类:增加“木料〞与“颜色〞数据;〔4〕而后又由shirt类出发〔作为基类〕,派生出cap〔帽子〕类:增加“样式〞数据。2.对应于要对各类数据所进行的操作,而设立出类的如下几个成员函数。〔1〕构造函数通过传递来的实参数据,来构造出每一对象所具有的各数据成员。如基类base需要传递place、count与price三项数据,而派生类shirt那么需在base数据的根底上增加第四项即布料数据material等。〔2〕商品的进库〔增加库存量〕voidin_something(intadd_cnt);将对象的库存量count增加一个数量add_cnt。〔3〕商品的出库〔减少库存量〕voidout_something(intdel_cnt);将对象的库存量count减少一个数量del_cnt。〔4〕该类货品总价格的计算doubletotal_price();通过使用“price*count〞计算并返回对象所代表货品的总价格。〔5〕对象数据的输出。在屏幕上显示出对象所拥有的当前数据。代码:#include<iostream>#include<string>usingnamespacestd;classbase{protected: stringplace; intcount; doubleprice;public: base(stringpl,doublepr,intc); voidin_something(intadd_cnt); voidout_something(intdel_cnt);};classwardrobe:publicbase{ stringcolor; stringwood;public: wardrobe(stringpl,doublepr,intc,stringco,stringwo):base(pl,pr,c) { color=co; wood=wo; } voidprint();};classshirt:publicbase{protected: stringmaterial;public: shirt(stringpl,doublepr,intc,stringma):base(pl,pr,c) { material=ma; } voidprint();};classcap:publicshirt{ stringstyle;public: cap(stringpl,doublepr,intc,stringma,stringst):shirt(pl,pr,c,ma) { style=st; } voidprint();};base::base(stringpl,doublepr,intc){ place=pl; price=pr; count=c;}voidbase::in_something(intadd_cnt){ count+=add_cnt; }voidbase::out_something(intdel_cnt){ count-=del_cnt; if(count<0)count=0;}voidshirt::print(){ cout<<"衬衣\t产地:"<<place<<"\t布料:"<<material<<"\n单价:"<<price<<"\t数量:"<<count<<"\t总价:"<<price*count<<endl;}voidcap::print() { cout<<"帽子\t产地:"<<place<<"\t布料:"<<material<<"\t样式:"<<style<<"\n单价:"<<price<<"\t数量:"<<count<<"\t总价:"<<price*count<<endl;}voidwardrobe::print() { cout<<"立柜\t产地:"<<place<<"\t颜色:"<<color<<"\t木料:"<<wood<<"\n单价:"<<price<<"\t数量:"<<count<<"\t总价:"<<price*count<<endl;}intmain(void){ shirts("广州",55.8,20,"棉"); capc("苏州",23.5,30,"帆布","A"); wardrobew("福建",1200,10,"红色","樟木"); stringa; cout<<"有如下商品:"<<endl; s.print(); c.print(); w.print(); inttemp; while(a!="0") { cout<<"输入相应物品进行相应操作〔衬衣:s帽子:c立柜:w结束:0〕"<<endl; cin>>a; if(a=="s"){ cout<<"+为入库-为出库?为查询";cin>>a; if(a=="+"){cout<<"入库数量:";cin>>temp;s.in_something(temp);} if(a=="-"){cout<<"出库数量:";cin>>temp;s.out_something(temp);} if(a=="?")s.print(); } elseif(a=="c"){ cout<<"+为入库-为出库?为查询";cin>>a; if(a=="+"){cout<<"入库数量:";cin>>temp;c.in_something(temp);} if(a=="-"){cout<<"出库数量:";cin>>temp;c.out_something(temp);} if(a=="?")c.print(); } elseif(a=="w"){ cout<<"+为入库-为出库?为查询";cin>>a; if(a=="+"){cout<<"入库数量:";cin>>temp;w.in_something(temp);} if(a=="-"){cout<<"出库数量:";cin>>temp;w.out_something(temp);} if(a=="?")w.print(); } elseif(a=="0"){s.print();c.print();w.print();} elsecout<<"有误重新"; } return0;}运行结果:有如下商品:衬衣产地:广州布料:棉单价:55.8数量:20总价:1116帽子产地:苏州布料:帆布样式:A单价:23.5数量:30总价:705立柜产地:福建颜色:红色木料:樟木单价:1200数量:10总价:12000输入相应物品进行相应操作〔衬衣:s帽子:c立柜:w结束:0〕s+为入库-为出库?为查询+入库数量:20输入相应物品进行相应操作〔衬衣:s帽子:c立柜:w结束:0〕c+为入库-为出库?为查询-出库数量:100输入相应物品进行相应操作〔衬衣:s帽子:c立柜:w结束:0〕w+为入库-为出库?为查询?立柜产地:福建颜色:红色木料:樟木单价:1200数量:10总价:12000输入相应物品进行相应操作〔衬衣:s帽子:c立柜:w结束:0〕0衬衣产地:广州布料:棉单价:55.8数量:40总价:2232帽子产地:苏州布料:帆布样式:A单价:23.5数量:0总价:0立柜产地:福建颜色:红色木料:樟木单价:1200数量:10总价:12000Pressanykeytocontinue实验四〔2010-4多态程序设计实验目的:〔1〕掌握运算符重载的方法; 运算符其实相当于一个函数只不过我们平时使用的是它的隐式形式重载是函数名不变,带入函数的参数个数不变,但参数类型必须改变,返回值类型改变,功能也随之发生相应变化其实质是将函数功能拓展函数重载的方法与定义一个函数的方法几乎完全相同格式为:返回值类型作用域::重载函数名〔参数表〕{函数定义}注意:类其实也可以看做是一种数据类型所以return之后可以返回一个对象〔2〕掌握使用虚函数实现动态多态性; 也叫动态联编是通过指针实现的练习工程1.定义Point类,有坐标x,y两个成员变量,利用友元函数对Point类重载“++〞运算符,实现对坐标值的改变。具体要求如下:编写程序定义Point类,在类中定义整型的私有成员变量x,y;在类中定义两个友元函数,分别重载前置++和后置++;编写主函数测试。注意函数有无返回值的区别,以及返回值是否带有&应用符号。1程序代码:#include<iostream.h>//usingnamespacestd;classPoint{ intx,y;public: Point(){} Point(int&a,int&b) { x=a,y=b; } friendPointoperator++(Point&c){ inta,b; a=++c.x; b=++c.y; cout<<"->x="<<a<<",y="<<b<<endl; returnc; } friendPointoperator++(Point&c,int){ inta,b; a=c.x++; b=c.y++; cout<<"->x="<<a<<",y="<<b<<endl; returnc; } voidshow() { cout<<"->x="<<x<<",y="<<y<<endl; }};intmain(void){ cout<<"x,y"<<endl; inta,b; cin>>a;cin>>b; Pointob1(a,b); cout<<"Point++";ob1++; cout<<"NowPoint"; ob1.show(); cout<<"++Point";++ob1; cout<<"NowPoint"; ob1.show(); return0;}运行结果:x,y56Point++->x=5,y=6NowPoint->x=6,y=7++Point->x=7,y=8NowPoint->x=7,y=8Pressanykeytocontinue2.定义Point类,有坐标x,y两个成员变量,利用运算符重载对Point类重载“++〞运算符,实现对坐标值的改变。具体要求如下:编写程序定义Point类,在类中定义整型的私有成员变量x,y;定义成员函数Point&operator++();Pointoperator++(int);以实现对Point类重载“++〞运算符,分别重载前置++和后置++;编写主函数测试。2程序代码:#include<iostream>usingnamespacestd;classPoint{ intx,y;public: Point(){} Point(int&a,int&b) { x=a; y=b; } Pointoperator++(int){ inta,b; a=x++; b=y++; cout<<"Point++->x="<<a<<",y="<<b<<endl; return*this; } Pointoperator++(){ inta,b; a=++x; b=++y; cout<<"++Point->x="<<a<<",y="<<b<<endl; return*th

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论