• 617.00 KB
  • 2022-04-22 11:51:09 发布

《C 面向对象程序设计》习题与上机解答-提交稿-陈维兴.doc

  • 98页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'《C++面向对象程序设计》习题与上机实验题解答陈维兴陈昕编著人民邮电出版社98 目录第1章面向对象方法概述1.1习题参考解答第2章C++的初步知识2.1习题参考解答2.2上机实验题参考解答第3章类和对象3.1习题参考解答3.2上机实验题参考解答第4章类和对象的进一步讨论4.1习题参考解答4.2上机实验题参考解答第5章继承与派生5.1习题参考解答5.2上机实验题参考解答第6章多态性与虚函数6.1习题与参考解答6.2上机实验题与参考解答第7章运算符重载7.1习题参考解答7.2上机实验题参考解答第8章模板8.1习题参考解答8.2上机实验题参考解答第9章C++的输入和输出9.1习题参考解答9.2上机实验题参考解答第10章异常处理和命名空间10.1习题参考解答10.2上机实验题参考解答第11章综合设计与实现11.1习题参考解答11.2上机实验题参考解答98 第1章面向对象方法概述1.1习题参考解答【1.1】【解】面向过程程序设计的主要特征是:程序由过程定义和过程调用组成(所谓过程,简单地说,就是程序执行某项操作的一段代码,函数是最常用的过程。),从这个意义出发,基于面向过程的程序可以用以下的公式来表述:程序=过程+调用【1.2】【解】面向过程程序设计中普遍采用的优化方法是使用结构化程序设计方法,其局限性至少有以下几个方面:(1)面向过程程序设计方法开发软件的生产效率低下(2)面向过程程序设计方法难以应付日益庞大的信息量和多样的信息类型(3)面向过程程序设计方法难以适应各种新环境【1.3】【解】面向对象程序设计是一种新的程序设计范型。这种范型的主要特征是:程序=对象+消息对于面向对象的程序设计,程序员注重的是类的设计和编写,即问题域中涉及几个类,各个类之间的关系如何,每个类包含哪些数据和函数(操作代码),再由类生成其对象。程序中的一切操作都是通过向对象发送消息来实现的,对象接收到消息后,启动有关方法(通过成员函数)完成相应的操作。【1.4】【解】现实世界中的对象,具有以下特性:(1)有一个名字:每一个对象必须有一个名字,称为对象名,以区别于其他对象;(2)有一组属性:用属性来描述它的某些特征,一般可以用数据来表示,所有的属性都有值;(3)有一组行为:对象的行为或功能也称为方法,一般用一组操作来描述;(4)有一组接口:除施加于对象内部的操作外,对象还提供了一组公有操作用于与外界接口,从而可以与其他对象建立关系。【1.5】【解】在面向对象程序设计中,对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。“类”就是具有相同的数据(属性)和相同的操作代码(函数)的一组对象的集合。类和对象之间的关系是抽象和具体的关系。类是多个对象进行综合抽象的结果,一个对象是类的一个实例。【1.6】什么是消息?98 【解】面向对象程序设计技术必须提供一种机制允许一个对象与另一个对象的交互。这种机制叫消息传递。一个对象向另一个对象发出的请求被称为“消息”。【1.7】【解】在面向对象程序设计中的消息传递实际是对现实世界中的信息传递的直接模拟。调用对象中的函数就是向该对象传送一个消息,要求该对象实现某一行为(功能)。对象所能实现的行为(功能),在程序设计方法中称为方法,它们是通过调用相应的函数来实现的,在C++语言中方法是通过成员函数来实现的。【1.8】【解】在面向对象程序设计中,抽象是通过特定的实例(对象)抽取共同特性后形成概念的过程。C和C++中的数据类型就是对一批具体的数的抽象。例如,“整型数据”是对所有整数的抽象。封装是面向对象程序设计方法的一个重要特性,所谓封装具有两方面的含义:一是将有关的数据和操作代码封装在一个对象中,各个对象相对独立、相不干扰。二是将对象中某些数据与操作代码对外隐蔽,即隐蔽其内部细节,只留下少量接口,以便与外界联系,接收外界的消息。这种对外界隐蔽的做法称为信息隐蔽。信息隐蔽有利于数据安全,防止无关人员访问和修改数据。【1.9】【解】以面向对象程序设计的观点,继承所表达的是类之间相关的关系。这种关系使得某一类可以继承另外一个类的特征和能力。若类之间具有继承关系,则它们之间具有下列几个特性:(1)类间具有共享特征(包括数据和操作代码的共享);(2)类间具有差别或新增部分(包括非共享的数据和操作代码);(3)类间具有层次结构。【1.10】【解】从继承源来分,继承分为单继承和多继承。单继承是指每个派生类只直接继承了一个基类的特征。例如,图1.1表示了一种单继承关系。它表示Windows操作系统的窗口之间的继承关系。窗口对话窗口编辑窗口图1.1单继承示意图多继承是指多个基类派生出一个派生类的继承关系。多继承的派生类直接继承了不止一个基类的特征。例如,小孩喜欢的玩具车即继承了车的一些特性,还继承了玩具的一些特征。如图1.2所示。车玩具98 玩具车图1.2多继承示意图【1.11】【解】多态性是面向对象程序的重要特征。多态性是指不同的对象收到相同的的消息时执行不同的操作。例如,我们同样双击Window系统桌面上的图标时,有的是打开多媒体播放器,有的是打开资源管理器。多态性增强了软件的灵活性和重用性,为软件的开发与维护提供了极大的便利。尤其是采用了虚函数和动态联编机制后,允许用户以更为明确、易懂的方式去建立通用的软件。【1.12】【解】面向对象程序设计的优点主要包括以下几个方面:(1)可提高程序的重用性面向对象程序设计方法能比较好地解决软件重用的问题。对象所固有的封装性和信息隐藏等机理,使得对象内部的实现与外界隔离,具有较强的独立性,它可以作为一个大粒度的程序构件,供同类程序直接使用。有两种方法可以重复使用一个对象类:一种方法是建立在各种环境下都能使用的类库,供相关程序直接使用;另一种方法是从它派生出一个满足当前需要的新类。继承性机制使得子类不仅可以重用其父类的数据和程序代码,而且可以在父类代码的基础上方便地修改和扩充,这种修改并不影响对原有类的使用。(2)可控制程序的复杂性面向对象程序设计方法采用了封装和信息隐藏技术,把数据及对数据的操作放在一个个类中,作为相互依存、不可分割的整体来处理。这样,在程序中任何要访问这些数据的地方都只需简单地通过传递信息和调用方法来进行,这就有效地控制了程序的复杂性。(3)可改善程序的可维护性在面向对象程序设计方法中,对对象的操作只能通过消息传递来实现,所以只要消息模式即对应的方法界面不变,方法体的任何修改不会导致发送消息的程序修改,这显然对程序的维护带来了方便。另外,类的封装和信息隐藏机制使得外界对其中的数据和程序代码的非法操作成为不可能,这也就大大地减少了程序的错误率。(4)能够更好地支持大型程序设计类是一种抽象的数据类型,所以类作为一个程序模块,要比通常的子程序的独立性强的多,面向对象技术在数据抽象上又引入了动态连接和继承性等机制,进一步发展了基于数据抽象的模块化设计,使其更好地支持大型程序设计。(5)增强了计算机处理信息的范围面向对象程序设计方法把描述事物静态属性的数据结构和表示事物动态行为的操作放在一起构成一个整体,完整地、自然地表示客观世界中的实体。用类来直接描述现实世界中的类型,可使计算机系统的描述和处理对象从数据扩展到现实世界和思维世界的各种事物,这实际上大大扩展了计算机系统处理的信息量和信息类型。98 第2章C++的初步知识2.1习题参考解答【2.1】【解】C++语言的主要特点表现在两个方面,一是全面兼容C,并对C的功能作了不少扩允,二是增加了面向对象的机制。具体表现为:(1)C++是C的超集,C++保持与C的兼容,这就使许多C代码不经修改就可以为C++所用,用C编写的众多的库函数和实用软件基本上可以不加修改地用于C++。(2)C++是一个更好的C,它保持了C的简洁、高效和接近汇编语言等特点,并对C的功能作了不少扩允。用C++编写的程序比C更安全,可读性更好,代码结构更为合理。(3)用C++编写的程序质量高,从开发时间、费用到形成的软件的可重用性、可扩充性、可维护性和可靠性等方面有了很大的提高,使得大中型的程序开发变得更加容易。(4)增加了面向对象的机制,C++几乎支持所有的面问对象程序设计特征,体现了近20年来在程序设计和软件开发领域出现的新思想和新技术。C++语言最有意义的方面是支持面向对象的特征,然而,由于C++与C保持兼容,使得C++不是一个纯正的面向对象的语言,C++既可用于面向过程的结构化程序设计,也可用于面向对象的程序设计。【2.2】【解】#include//编译预处理命令usingnamespacestd;//使用命令空间stddoublecircle(doubler)//定义函数circle{return3.14*r*r;}doubletriangle(doubleh,doublew)//定义函数triangle{return0.5*h*w;}intmain()//定义主函数main{doubler,h,w;doublecs,ts;cout<<"Inputr,h,w:";cin>>r>>h>>w;//输入圆的半径和三角形高和底的值cs=circle(r);//调用函数circlets=triangle(h,w);//调用函数trianglecout<<"Theareaofcircleis:"<#includeusingnamespacestd;intmain(){floatx,y;cout<<"pleaseinput2floatstox,y:";cin>>x>>y;floatz=pow(x,y);cout<<"pow("<usingnamespacestd;intmain()98 {int*p=newint[20];//动态分配20个整型内存空间*p=1;*(p+1)=1;//对前面2个内存空间赋值1cout<<*p<<"t"<<*(p+1)<<"t";p=p+2;//p指向第3个内存空间for(inti=3;i<=20;i++){*p=*(p-1)+*(p-2);cout<<*p<<"t";if(i%5==0)cout<#includeusingnamespacestd;doublesroot(inti){returnsqrt(i);}doublesroot(longl){returnsqrt(l);}doublesroot(doubled){returnsqrt(d);}intmain(){inti=12;longl=1234;doubled=12.34;cout<<"i的二次方根是:"<CloseWorkspace(关闭工作区)”命令,则结束对该程序的的操作。若要退出VC++环境,则执行“File(文件)->Exit(退出)”命令。【运行结果】Hello!Thisisaprogram.【2.2】【错误分析】编译程序,提示有4个error错误,1个warming错误。①编译出错信息告知在第3行有2个error错误,第1个错误的原因是cout未经声明,第2个错误的原因是运算符“<<”不合法。这都是因为流对象cout是标准的输出流对象,它在文件iostream中声明,因此必须包含头文件iostream。因此应添加以下语句:#includeusingnamespacestd;98 ②编译出错信息告知在第5行有2个error错误。第1个error错误的原因是运算符“<<”不合法,原因与第3行的相同。第5行的第2个error错误原因是第5行少了1个分号“;”,这是因为每条语句需要由分号作为结束符。也许读者要问,明明这两个错误都是出现在第4行,为什么说成第5行有错呢?这是因为C++允许将一条语句分写成几行,检查完第4行没有分号后,必须检查下一行,直到发现第5行的“}”前都没有“;”时,才判定出错。因此在第5行报错。修改方法是:在第5行语句的末尾加上“;”。③编译出错信息告知第5行有1个warming错误,原因是main函数默认的返回值类型是int,而main函数中没有返回值。修改方法:在“}”前加上返回语句“return0;”。【修改后的程序】//test2_2_1_2.cpp#includeusingnamespacestd;intmain(){cout<<"Hello!n";cout<<"WelcometoC++!"<usingnamespacestd;intmain(){intx,y;x=5;y=6;intz=x*y;cout<<"x*y="<usingnamespacestd;intmain(){intx,y;x=5;y=6;98 intz=x*y;cout<<"x*y="<usingnamespacestd;intmain(){voidfun(int,int&);intx,y;fun(3,x);fun(4,y);cout<<"x+y=<usingnamespacestd;intmain(){voidfun(int,int&);intx,y;fun(3,x);fun(4,y);cout<<"x+y="<usingnamespacestd;intmaxl(intx,inty){return(x>y?x:y);}intmaxl(intx,inty,intz){inttemp=maxl(x,y);return(temp>z?temp:z);}doublemaxl(doublex,doubley){return(x>y?x:y);}doublemaxl(doublex,doubley,doublez){doubletemp=maxl(x,y);return(temp>z?temp:z);}charmaxl(charx,chary){return(x>y?x:y);}intmaxl(charx,chary,charz){inttemp=maxl(x,y);return(temp>z?temp:z);}intmain(){intx1,x2;doubled1,d2;charc1,c2;x1=maxl(3,5);x2=maxl(4,5,8);c1=maxl("a","b");c2=maxl("d","e","h");d1=maxl(3.1,5.6);d2=maxl(15.3,13.4,27.8);cout<<"maxl(3,5)="<usingnamespacestd;voidchange(char&,char&);intmain(){charx,y;cin>>x>>y;if(xusingnamespacestd;classCircle{public:Circle(floatr){radius=r;}floatarea(){return3.14*radius*radius;}private:floatradius;};intmain(){floatr;cout<<"请输入圆的半径:";cin>>r;Circlep(r);cout<<"半径为"<usingnamespacestd;classcylinder{public:cylinder(doublea,doubleb);voidvol();private:doubler,h;doublevolume;};cylinder::cylinder(doublea,doubleb){r=a;h=b;volume=3.141592*r*r*h;}voidcylinder::vol(){cout<<"volumeis:"<usingnamespacestd;classDate{public:Date(){}Date(inty,intm,intd){year=y;mon=m;day=d;}Date(Date&d){year=d.year;mon=d.mon;day=d.day;}voidSetDate(intY,intm,intd)98 {year=Y;mon=m;day=d;}voidprintDate(){cout<<"日期是:"<usingnamespacestd;#includeclassmagic{//声明魔方类magicpublic:voidgetdata();//输入初值成员函数voidsetfirstmagic();//设置初始魔方成员函数voidgeneratemagic();//生成最终魔方成员函数voidprintmagic();//显示魔方成员函数private:intm[4][4];intstep;//相邻元素之间的差值intfirst;//起始值intsum;//最大元素值和最小元素值的和};voidmagic::getdata()//输入初值成员函数{cout<<"输入4*4魔方起始值:";cin>>first;cout<<"输入相邻元素差值:";cin>>step;}voidmagic::setfirstmagic()//设置初始魔方成员函数{inti,j;inttmp;tmp=first;for(i=0;i<4;i++)for(j=0;j<4;j++){m[i][j]=tmp;tmp+=step;}}voidmagic::generatemagic()//生成最终魔方成员函数{sum=m[0][0]+m[3][3];for(inti=0,j=0;i<4;i++,j++)m[i][j]=sum-m[i][j];for(i=0,j=3;i<4;i++,j--)m[i][j]=sum-m[i][j];}98 voidmagic::printmagic()//显示魔方成员函数{inti,j;for(i=0;i<4;i++){for(j=0;j<4;j++)cout<#includeusingnamespacestd;constlen=5;intmain(){inti;voidReverse(strings[]);98 stringstr[len]={"Germany","Japan","America","Britain","France"};cout<<"按逆转前的顺序输出字符串:"<usingnamespacestd;classCTest{public:CTest(){x=20;}voiduse_friend();private:intx;friendvoidfriend_f(CTestfri);};voidfriend_f(CTestfri){fri.x=55;98 }voidCTest::use_friend(){CTestfri;this->friend_f(fri);//错误,友元函数不是成员函数,//所以不能用this->调用友元函数::friend_f(fri);}intmain(){CTestfri,fri1;fri.friend_f(fri);//错误友元函数不是成员函数,//所以不能用“对象.函数名”调用友元函数friend_f(fri1);return0;}【4.15】【解】#includeusingnamespacestd;classCTest{public:constinty2;CTest(inti1,inti2):y1(i1),y2(i2){y1=10;//错误,y1是用const定义的,不能修改x=y1;}intreadme()const;...private: intx;constinty1;};intCTest::readme()const{inti;i=x;x++;//错误,函数定义用了const,表示该函数不能修改对象returnx;}intmain(){CTestc(2,8);inti=c.y2;c.y2=i;//错误,y2是常量,不能修改i=c.y1;//错误,y1私有变量,不能直接存取return0;}98 【4.16】【解】本程序的运行结果如下:InitdefaInitdefaInitdefaInit35【4.17】【解】实现本题功能的程序如下:#includeusingnamespacestd;classStudent{public:Student(intn,floats):num(n),score(s){}voiddisplay();private:intnum;floatscore;};voidStudent::display(){cout<<"学号:"<display();return0;}本程序的运行结果如下:学号:1002成绩:75.5学号:1004成绩:99学号:1006成绩:86【4.18】【解】实现本题功能的程序如下:#includeusingnamespacestd;classStudent{public:Student(intn,floats):num(n),score(s)98 {}intnum;floatscore;};intmain(){Studentstu[6]={Student(1001,88.5),Student(1002,75.5),Student(1003,68.5),Student(1004,99.0),Student(1005,93.5),Student(1006,86.0)};voidmax(Student*);Student*p=&stu[0];max(p);return0;}voidmax(Student*arr){floatmax_score=arr[0].score;intk=0;for(inti=1;i<6;i++)if(arr[i].score>max_score){max_score=arr[i].score;k=i;}cout<<"学号:"<usingnamespacestd;classbook{public:book(inta,intb){qu=a;price=b;}voidshow_money(){cout<usingnamespacestd;classbook{public:book(inta,intb){qu=a;price=b;}voidshow_money(){cout<show_money();p--;}return0;}本程序的运行结果如下:250160904098 10【4.21】【解】实现本题功能的程序如下:#include#includeusingnamespacestd;classStudent{public:Student(intn,stringna,doubled){no=n;deg=d;name=na;sum+=d;num++;}staticdoubleavg(){returnsum/num;}staticinttotal(){returnnum;}voiddisp(){cout<#includeusingnamespacestd;classPoint{protected:doublex,y;public:voidsetvalue(doublex1,doubley1){x=x1;y=y1;}frienddoubledist(Pointp1,Pointp2){doubled=sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));returnd;}voiddisp(){cout<<"点("<#includeclassLocation{public:Location(double,double);//构造函数doubleGetx()//成员函数,取x坐标的值{returnx;}doubleGety()//成员函数,取y坐标的值{returny;}doubledistance(Location&);//成员函数,求给定两点之间的距离frienddoubledistance(Location&,Location&);//友元函数,求给定两点之间的距离private:doublex,y;};Location::Location(doublea,doubleb){x=a;y=b;}doubleLocation::distance(Location&p){doubledx=x-p.x;doubledy=y-p.y;return(double)sqrt(dx*dx+dy*dy);}doubledistance(Location&p1,Location&p2){doubledx=p1.x-p2.x;doubledy=p1.y-p2.y;returnsqrt(dx*dx+dy*dy);98 }intmain(){LocationA(-10,-20),B(-40,60);cout<<"A("<usingnamespacestd;classStudent{public:voidaccount(doubles);staticdoublesum();staticdoubleaverage();private:doublescore;staticdoubletotal_score;staticdoublecount;};doubleStudent::total_score=0;doubleStudent::count=0;voidStudent::account(doubles){score=s;total_score=total_score+score;count=count+1;}doubleStudent::sum(){cout<<"所有学生的成绩之和是:";returntotal_score;}doubleStudent::average(){cout<<"学生的平均成绩是:";returntotal_score/count;}intmain()98 {Studentstud[10];intn;doubles;cout<<"请输入学生的人数(1--10):";cin>>n;for(inti=0;i>s;stud[i].account(s);}cout<usingnamespacestd;classTime{public:Time(inth,intm,ints){hours=h;minutes=m;seconds=s;}voiddisplay(){cout<<"出生时间:"<usingnamespacestd;classperson{public:voidinput(){cout<<"编号:";cin>>no;cout<<"姓名:";cin>>name;}voiddisp(){cout<<"编号:"<>depart;cout<<"成绩:";cin>>degree;}voiddisp(){person::disp();cout<<"班号:"<>prof;cout<<"部门:";cin>>depart;}voiddisp(){person::disp();cout<<"职称:"<usingnamespacestd;classbase{//基类char*name;//姓名intage;//年龄public:98 base(){}base(charna[],inta){name=newchar[strlen(na)+1];strcpy(name,na);age=a;}char*getname(){returnname;}intgetage(){returnage;}~base(){delete[]name;}};classleader:virtualpublicbase{//领导类char*job;//职务char*dep;//部门public:leader(){}leader(charna[],intn,charjb[],chardp[]):base(na,n){job=newchar[strlen(jb)+1];strcpy(job,jb);dep=newchar[strlen(dp)+1];strcpy(dep,dp);}char*getjob(){returnjob;}char*getdep(){returndep;}~leader(){delete[]job;delete[]dep;}};classengineer:virtualpublicbase{//工程师类char*major;//专业char*prof;//职称public:engineer(){}engineer(charna[],intn,charmaj[],charpf[]):base(na,n){major=newchar[strlen(maj)+1];strcpy(major,maj);prof=newchar[strlen(pf)+1];strcpy(prof,pf);}char*getmajor(){returnmajor;}char*getprof()98 {returnprof;}~engineer(){delete[]major;delete[]prof;}};classchairman:publicleader,publicengineer{//主任工程师类public:chairman(){};chairman(charna[],intn,charjb[],chardp[],charmaj[],charpf[]):base(na,n),leader(na,n,jb,dp),engineer(na,n,maj,pf){}voiddispchairman(){cout<#includeusingnamespacestd;classPerson{//公共基类Personpublic:Person(intno1,stringname1,stringsex1,intage1)//构造函数{no=no1;name=name1;sex=sex1;age=age1;}voiddisplay()//输出基本信息{cout<<"编号:"<alist[j+1]){temp=alist[j];alist[j]=alist[j+1];alist[j+1]=temp;}}//并将主函数修改为:intmain(){SortArrays(5);s.Input();//输入整数s.Display("显示排序以前的");//显示排序以前的整数s.Sort();//进行排序s.Display("显示排序以后的");//显示排序以后的整数return0;}【运行结果】程序的一次执行结果如下:MyArray类对象已创建.SortArray类对象已创建.请从键盘输入5个整数:1133552244↙显示排序以前的5个整数:1133552244显示排序以后的5个整数:1122334455SortArray类对象被撤销.MyArray类对象被撤销.(3)【参考程序】在第(1)步的基础上增加下面的参考代码:classReArray:publicMyArray{public:voidReverse();ReArray(intleng);virtual~ReArray();};ReArray::ReArray(intleng):MyArray(leng){cout<<"ReArray类对象已创建."<#includeusingnamespacestd;classMyArray{//声明一个基类MyArraypublic:MyArray(intleng);//构造函数~MyArray();//析构函数voidInput();//输入数据的成员函数voidDisplay(string);//输出数据的成员函数protected:int*alist;//基类中存放一组整数intlength;//整数的个数};MyArray::MyArray(intleng){if(leng<=0){cout<<"errorlength";exit(1);}98 alist=newint[leng];length=leng;if(alist==NULL){cout<<"assignfailure";exit(1);}cout<<"MyArray类对象已创建."<>*p;}classSortArray:virtualpublicMyArray{//声明MyArray为虚基类,为了在NewArray类的继承中没有二义性public:voidSort();SortArray(intleng):MyArray(leng){cout<<"SortArray类对象已创建."<alist[j+1]){temp=alist[j];alist[j]=alist[j+1];alist[j+1]=temp;}}classReArray:virtualpublicMyArray{//声明MyArray为虚基类,为了在NewArray类的继承中没有二义性public:voidReverse();ReArray(intleng);virtual~ReArray();};ReArray::ReArray(intleng):MyArray(leng){cout<<"ReArray类对象已创建."<usingnamespacestd;classarea_cl{protected:doubleheight;doublewidth;public:area_cl(doubler,doubles){height=r;width=s;}virtualdoublearea()=0;};classrectangle:publicarea_cl{public:rectangle(doubler,doubles):area_cl(r,s){};doublearea(){returnheight*width;}};classisosceles:publicarea_cl{public:isosceles(doubler,doubles):area_cl(r,s){};doublearea(){returnheight*width/2;}};intmain(){area_cl*p;rectangleb(10.0,5.0);isoscelesi(4.0,6.0);p=&b;cout<<"Therectangle"sareais"<area()<area()<usingnamespacestd;classBase{public:Base(){}Base(doubleh1){h=h1;}virtualvoiddisp()//虚函数disp{cout<<"长方体和圆柱体的高度都是:"<surface_area()<volume()<surface_area()<volume()<surface_area()<volume()<print()调用的都是Stock::print(),而不是调用Der1_Stock::print()或Der2_Stock::print(),这是因为基类和派生类中定义的print()函数的返回值类型、参数类型和个数均相同,但基类中定义的print()未声明成虚函数(virtual),这时的函数调用是在编译时静态联编的。【6.2】【参考程序】修改后的程序如下://test6_2cpp#includeusingnamespacestd;classStock{public:virtualvoidprint()//修改的地方{cout<<"Stockclass.n";}};classDer1_Stock:publicStock{98 public:voidprint(){cout<<"Der1_Stockclass.n";}};classDer2_Stock:publicStock{public:voidprint(){cout<<"Der2_Stockclass.n";}};intmain(){Stocks1;Stock*ptr;Der1_Stockd1;Der2_Stockd2;ptr=&s1;ptr->print();ptr=&d1;ptr->print();ptr=&d2;ptr->print();return0;}【6.3】【参考程序】//test6_3.cpp#include#includeusingnamespacestd;classShape{//定义一个公共基类public:Shape(doublea,doubleb){x=a;y=b;}virtualvoidshow_perimeter()=0;//定义一个纯虚函数,作为界面接口protected:doublex,y;};classTriangle:publicShape{//定义等腰三角形派生类public:Triangle(doublea,doubleb):Shape(a,b){};voidshow_perimeter()//虚函数重定义,用作求三角形的周长{cout<<"Trianglewithheight"<show_perimeter();//计算等腰三角形周长p=&s;p->show_perimeter();//计算矩形周长p=&c;p->show_perimeter();//计算圆形周长return0;}【运行结果】Trianglewithheight10andbase6hasanperimeterof26.8806Squarewithdimension10*6hasanperimeterof32Circlewithradius10hasanperimeterof62.832【结果分析】在公共基类Shape中定义一个虚函数show_perimeter,作为界面接口,在3个派生类Triangle、Square和Circle中重新定义了虚函数show_perimeter,分别用于计算等腰三角形、矩形和圆形的周长。由于p是基类的对象指针,用同一种调用形式"p->show_perimeter98 ();",就可以调用同一类族中不同类的虚函数。这就是多态性,对同一消息,不同的对象有不同的响应方式。【6.4】【参考程序】//test6_4.cpp#includeusingnamespacestd;classContainer{//声明抽象类Containerprotected:doubleradius;public:Container(doubleradius1);//抽象类Container的构造函数virtualdoublesurface_area()=0;//纯虚函数surface_areavirtualdoublevolume()=0;//纯虚函数volume};Container::Container(doubleradius1)//定义抽象类Container的构造函数{radius=radius1;}classcube:publicContainer//声明一个正方体派生类cube{public:cube(doubleradius1):Container(radius1){}doublesurface_area()//定义虚函数surface_area{return6*radius*radius;}doublevolume()//定义虚函数volume{returnradius*radius*radius;}};classsphere:publicContainer//声明一个球体派生类sphere{public:sphere(doubleradius1):Container(radius1){};doublesurface_area()//纯虚函数surface_area{return4*3.1416*radius*radius;}doublevolume()//纯虚函数volume{return3.1416*radius*radius*radius*4/3;}};classcylinder:publicContainer//声明一个圆柱体派生类cylinder{doubleheight;public:cylinder(doubleradius1,doubleheight1):Container(radius1){height=height1;98 }doublesurface_area()//定义虚函数surface_area{return2*3.1416*radius*(radius+height);}doublevolume()//定义虚函数volume{return3.1416*radius*radius*height;}};intmain(){Container*ptr;//定义抽象类Shape的对象指针ptrcubeobj1(5.0);//定义正方体的类对象obj1sphereobj2(5.0);//定义球体的类对象obj2cylinderobj3(5.0,6.0);//定义圆柱体的类对象obj2ptr=&obj1;//指针ptr指向正方体类对象obj1cout<<"这个正方体的表面积是:"<surface_area()<volume()<surface_area()<volume()<surface_area()<volume()<”。【7.4】【解】B【7.5】【解】B说明:C++中,插入运算符“<<”和提取运算符“>>”只能作为非成员函数重载,所以选项B)是正确的。【7.6】【解】D【7.7】【解】本程序的运行结果如下:14.5【7.9】【解】实现本题功能的程序如下:#include#includeusingnamespacestd;constintrow=2;constintcol=3;classarray{public:array();//构造函数array(inta,intb,intc,intd,inte,intf);voidget_array();//由键盘输入数组的值voiddisplay();//显示数组的值arrayoperator+(array&X);//将两个数组相加arrayoperator-(array&X);//将两个数组相减private:98 intvar[row][col];};array::array(){for(inti=0;i>var[i][j];}voidarray::display()//显示数组的值{for(inti=0;i#includeusingnamespacestd;constintrow=2;constintcol=3;classarray{public:array();//构造函数array(inta,intb,intc,intd,inte,intf);voidget_array();//由键盘输入数组的值voiddisplay();//显示数组的值friendarrayoperator+(array&X,array&Y);//将两个数组相加friendarrayoperator-(array&X,array&Y);//将两个数组相减98 private:intvar[row][col];};array::array(){for(inti=0;i>var[i][j];}voidarray::display()//显示数组的值{for(inti=0;i#include【7.11】【解】实现本题功能的程序如下:#includeusingnamespacestd;classDate{public:Date(){}Date(intm,intd,inty){month=m;day=d;year=y;}voidprint(){cout<year);n+=this->day;while(n>days[leap][this->month-1]){n-=days[leap][this->month-1];if(++(this->month)==13){this->month=1;(this->year)++;leap=isleap(this->year);}}this->day=n;return*this;}intmain(){Dated1(2,15,2000),d2;d1.print();d2=d1+365;d2.print();return0;}程序的运行结果是:2000.2.152001.2.14【7.12】【解】实现本题功能的程序如下:#includeusingnamespacestd;classMatrix{public:Matrix();friendMatrixoperator+(Matrix&,Matrix&);//声明重载运算符"+"friendostream&operator<<(ostream&,Matrix&);//声明重载运算符"<<"friendistream&operator>>(istream&,Matrix&);//声明重载运算符">>"98 private:intmat[2][4];};Matrix::Matrix(){for(inti=0;i<2;i++)for(intj=0;j<4;j++)mat[i][j]=0;}Matrixoperator+(Matrix&a,Matrix&b)//定义运算符"+"的重载函数{Matrixc;for(inti=0;i<2;i++)for(intj=0;j<4;j++){c.mat[i][j]=a.mat[i][j]+b.mat[i][j];}returnc;}istream&operator>>(istream&in,Matrix&m)//定义运算符">>"的重载函数{cout<<"inputvalueofmatrix:"<>m.mat[i][j];returnin;}ostream&operator<<(ostream&out,Matrix&m)//定义运算符"<<"的重载函数{for(inti=0;i<2;i++){for(intj=0;j<4;j++){out<>a;//用cin输入矩阵acin>>b;//用cin输入矩阵bcout<<"Matrixa:"<usingnamespacestd;修改成#include7.2上机实验题参考解答【7.1】【运行结果】76【结果分析】重载“++”运算符时,函数是通过传值的方法传递参数,函数体内对数据成员的改动无法传到函数体外。所以执行++a后,a.x的值没有变化。重载“--”运算符时采用引用参数传递操作数,所以执行--a后,a.x的值被修改。【7.2】【参考程序】//test7_2.cpp#include#includeusingnamespacestd;classTime{public:Time(inth=0,intm=0,ints=0);//构造函数Timeoperator+(Time&);//运算符重载函数,实现两个时间的相加voiddisptime(string);//输出时间函数private:inthours;//小时intminutes;//分钟intseconds;//秒钟};98 Time::Time(inth,intm,ints){hours=h;if(h<0){cout<<"时钟数小于0,请修正"<=60||m<0){cout<<"分钟数小于0或大于等于60,请修正"<=60||seconds<0){cout<<"秒钟数小于0或大于等于60,请修正"<usingnamespacestd;classContainer{public:Container(doubler=0,doublei=0);friendContaineroperator+(constContainerc1,constContainerc2);voidprint();private:doublereal,imag;};Container::Container(doubler,doublei){real=r;imag=i;}Containeroperator+(constContainerc1,constContainerc2){Containertemp;temp.real=c1.real+c2.real;temp.imag=c1.imag+c2.imag;returntemp;}voidContainer::print(){cout<<"("<usingnamespacestd;修改成#include98 即可顺利运行。第8章模板8.1习题参考解答【8.1】【解】所谓函数模板,实际上是建立一个通用函数,其函数返回类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。函数模板的声明格式如下:template返回类型函数名(模板形参表){函数体}也可以定义成如下形式:template返回类型函数名(模板形参表){函数体}【8.2】【解】函数模板与同名的非模板函数可以重载。在这种情况下,调用的顺序是:首先寻找一个参数完全匹配的非模板函数,如果找到了就调用它;若没有找到,则寻找函数模板,将其实例化,产生一个匹配的模板函数,若找到了,就调用它。【8.3】【解】所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回类型和形参类型不具体指定,用一个虚拟的类型来代表。使用类模板定义对象时,系统会根据实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。定义一个类模板与定义函数模板的格式类似,必须以关键字template开始,后面是尖括号括起来的模板参数,然后是类名,其格式如下:templateclass类名{98 类成员声明};也可以定义成如下形式:templateclass类名{类成员声明};【8.4】【解】A【8.5】【解】D【8.6】【解】C【8.7】【解】A【8.8】【解】D【8.9】【解】A【8.10】【解】本程序的运行结果如下:较小整数:6较小实数:0.5【8.11】【解】本程序的运行结果如下:100.23XThisisatest.说明:这个程序声明了两种类型的对象。ob1的两个参数分别为整型与双精度型,ob2的两个参数分别为字符型与字符串型。【8.12】【解】本程序的运行结果如下:最小的坐标:(3,16)最小的数:2.99【8.13】【解】在类模板体外定义成员函数min时“TCompare::min()”是错误的,应在成员函数名前缀上“类名<类型参数>::”,应该将此语句改为:TCompare::min()主函数中语句“Comparecom1(3,7);”是错误的,因为首先要将模板实例化,才能由模板生成对象。应该将此语句改为:Comparecom1(3,7);98 修改后,正确的程序如下:#includeusingnamespacestd;template//模板声明,其中为T类型参数classCompare{//类模板名为Comparepublic:Compare(Ta,Tb){x=a;y=b;}Tmin();private:Tx,y;};templateTCompare::min(){return(xcom1(3,7);cout<<"其中的最小值是:"<Typemin(Typea,Typeb,Typec){a=(ausingnamespacestd;templateTypemin(Typea,Typeb,Typec)//声明函数模板{a=(ausingnamespacestd;template//函数模板Typemax(Type*Array,intsize){inti,j=0;for(i=1;iArray[j]){j=i;}returnArray[j];}intmain(){intintArray[]={11,12,13,14,7,8,9};doubledoubleArray[]={11.2,12.3,13.2,14.5,14.8,8.7,9.3};cout<templatevoidsort(Type*Array,intsize){inti,j;for(i=0;iArray[j+1]){Typetemp=Array[j];Array[j]=Array[j+1];Array[j+1]=temp;}for(i=0;i<=size-1;i++)cout<usingnamespacestd;template//模板声明,其中为T类型参数classSum{//类模板名为Sumpublic:Sum(Ta,Tb,Tc){x=a;y=b;z=c;}Tadd(){returnx+y+z;}private:Tx,y,z;};intmain(){Sums1(3,7,9);//用类模板定义对象s1,此时T被int替代Sums2(12.34,56.78,67.89);//用类模板定义对象s2,此时T被double替代cout<<"三个整数的和是:"<usingnamespacestd;template//模板声明,其中为T类型参数classSum{//类模板名为Sum98 public:Sum(Ta,Tb,Tc);//声明构造函数的原型Tadd();//声明成员函数add的原型private:Tx,y,z;};template//模板声明Sum::Sum(Ta,Tb,Tc)//在类模板体外定义构造函数{x=a;y=b;z=c;}template//模板声明TSum::add()//在类模板体外定义成员函数add,返回类型为T{returnx+y+z;}intmain(){Sums1(3,7,9);//用类模板定义对象s1,此时T被int替代Sums2(12.34,56.78,67.89);//用类模板定义对象s2,此时T被double替代cout<<"三个整数的和是:"<usingnamespacestd;templateTmax(Ta[],intn)//定义函数模板max,可以求任意类型数组中的最大元素{inti;Tmax=a[0];for(i=1;iTmin(Ta[],intn)//定义函数模板min,可以求任意类型数组中的最小元素{inti;Tmin=a[0];for(i=1;ia[i])min=a[i];returnmin;}intmain(){inta[5]={11,22,33,44,55};doubleb[5]={1.1,2.2,3.3,4.4,5.5};charc[5]={"a","b","e","d","e"};cout<<"数组a中最大的元素是:"<#includeusingnamespacestd;templateclassArray{public:Array(Type*d,inti){data=d;n=i;}~Array(){}voidsort();//从大到小排序voidReverse();//将数组倒置voidfind(intk);//查找第k个元素的值Typesum();//求数组元素之和voiddisplay();//显示所有数组元素private:Type*data;intn;};templatevoidArray::sort()//采用冒泡排序法从大到小排序{inti,j;Typetemp;for(i=1;i=i;j--)if(data[j-1]voidArray::Reverse()//数组倒置{Typetemp;for(inti=0;ivoidArray::find(intk)//查找第k个元素的值{cout<TypeArray::sum()//求数组元素之和{Types=0;inti;for(i=0;ivoidArray::display()//显示所有数组元素{inti;for(i=0;ia1(a,8);cout<<"数组a:"<b1(b,9);cout<<"数组b:"<#includeusingnamespacestd;doublefact(intn);intmain(){for(intn=5;n<10;n++)cout<=1;i--)factor*=i;returnfactor;}程序的运行结果是:5!=1206!=7207!=50408!=403209!=362880【9.17】【解】实现本题功能的程序如下:#include#includeusingnamespacestd;intmain(){doublex;cout.precision(5);cout<<"xlnelogxn";for(x=2.0;x<=10.0;x++){cout.width(2);cout<#includeusingnamespacestd;intmain(){intflag=0,flag2=0;//flag=0表示前面的字符不是空格//flag2=0表示前面的字符不是"is"intsum=0;//sum记录"is"的个数charch;fstreamin("file1.txt",ios::in);if(!in){cerr<<"Erroropenfile.";return0;}while((ch=in.get())!=EOF)if(ch==""){if(flag!=1)flag=1;}else{if(flag==1&&ch=="i")flag2=1;if(flag2==1&&ch=="s"){sum++;flag2=0;}flag=0;}cout<#includeusingnamespacestd;intmain(){fstreamin("file1.txt",ios::in);if(!in){cerr<<"Erroropenfile.";return1;}fstreamout("file2.txt",ios::out);if(!out){cerr<<"Erroropenfile.";return2;}charch;while((ch=in.get())!=EOF)out<#includeusingnamespacestd;intmain(){ifstreamin;in.open("file1.txt",ios::in);if(!in){cerr<<"Erroropcnfile1.txt.";return1;}ofstreamout;out.open("file2.txt",ios::app);if(!out)98 {cerr<<"Erroropenfile2.txt.";return1;}charch;while((ch=in.get())!=EOF)out<#includeusingnamespacestd;intmain(){inti,j;cout<<"*";for(i=1;i<=9;i++)cout<#includeusingnamespacestd;intmain(){charch;inti=0;ifstreamfile;file.open("xyz.txt",ios::in);if(!file)//①{cout<<"xyz.txtcannotopen"<classMerchandise{public:Merchandise();~Merchandise();friendistream&operator>>(istream&in,Merchandise&s);friendostream&operator<<(ostream&out,Merchandise&s);private:intno;char*name;doubleprice;};Merchandise::Merchandise(){name=newchar[10];}Merchandise::~Merchandise(){delete[]name;}istream&operator>>(istream&in,Merchandise&s)98 {cout<<"输入一件商品的信息:"<>s.no;cout<<"商品名:";in>>s.name;cout<<"价格:";in>>s.price;returnin;}ostream&operator<<(ostream&out,Merchandise&s){out<<"输出这件商品的信息:"<>mer;cout<#includeusingnamespacestd;intmain(){fstreamfile1,file2,file3,file4;charfn1[10],fn2[10],fn3[10],ch;cout<<"输入源文件名1:";cin>>fn1;98 cout<<"输入源文件名2:";cin>>fn2;cout<<"输入目标文件名:";cin>>fn3;file1.open(fn1,ios::in);file2.open(fn2,ios::in);file3.open(fn3,ios::out);cout<<"文件"<usingnamespacestd;#includeclassStud{protected:intno;charname[10];intscore;public:Stud(){};voidgetdata(){cin>>no>>name>>score;if(score>100||score<0)throwname;}voiddisp(){cout<<""<#includeusingnamespacestd;doubletry_sqrt(doublea);intmain(){intx;while(1){cout<<"请输入一个数:";cin>>x;try//检查异常{cout<usingnamespacestd;classData_rec;classStudent;classTeacher;classEmployee;ostream&operator<<(ostream&output,Student&ob);istream&operator>>(istream&input,Student&ob);ostream&operator<<(ostream&output,Teacher&ob);istream&operator>>(istream&input,Teacher&ob);ostream&operator<<(ostream&output,Employee&ob);istream&operator>>(istream&input,Employee&ob);classData_rec{friendclassLinkList;98 protected:charname[20];intage;charid_number[18];staticData_rec*ptr;Data_rec*next;public:Data_rec(char*,int,char*);virtualvoidprint();virtualvoidinsert(){};};classStudent:publicData_rec{friendclassLinkList;intlevel;doublespent;public:Student(char*,int,char*,int,double);Student();voidprint();voidinsert();friendostream&operator<<(ostream&output,Student&ob);friendistream&operator>>(istream&itput,Student&ob);};classTeacher:publicData_rec{friendclassLinkList;doublehourly_wages;inthour;public:Teacher(char*,int,char*,double,int);voidprint();voidinsert();friendostream&operator<<(ostream&output,Teacher&ob);friendistream&operator>>(istream&itput,Teacher&ob);};classEmployee:publicData_rec{friendclassLinkList;doublesalary;public:Employee(char*,int,char*,double);voidprint();voidinsert();friendostream&operator<<(ostream&output,Employee&ob);friendistream&operator>>(istream&itput,Employee&ob);};98 classLinkList{Data_rec*head;public:LinkList(){head=NULL;}voidinsert_Data_rec(Data_rec*node);voiddele(char*name);voidprint_List();};Data_rec::Data_rec(char*name,intage,char*id_number){strcpy(Data_rec::name,name);strcpy(Data_rec::id_number,id_number);Data_rec::age=age;next=NULL;}voidData_rec::print(){cout<<"n姓名:"<>(istream&input,Student&ob){cout<<"EnterdataStudent:";input>>ob.name;input>>ob.age;98 input>>ob.id_number;input>>ob.level;input>>ob.spent;returninput;}Teacher::Teacher(char*name,intage,char*id_number,doublehourly_wages,inthour):Data_rec(name,age,id_number){Teacher::hourly_wages=hourly_wages;Teacher::hour=hour;}voidTeacher::print(){Data_rec::print();cout<<"n课时费:"<>(istream&input,Teacher&ob){cout<<"EnterdataStudent:";input>>ob.name;input>>ob.age;input>>ob.id_number;input>>ob.hourly_wages;input>>ob.hour;returninput;}Employee::Employee(char*name,intage,char*id_number,doublesalary):Data_rec(name,age,id_number){Employee::salary=salary;}voidEmployee::print(){Data_rec::print();cout<<"n月薪:"<>(istream&input,Employee&ob){cout<<"EnterdataStudent:";input>>ob.name;input>>ob.age;input>>ob.id_number;input>>ob.salary;returninput;}voidLinkList::insert_Data_rec(Data_rec*node){charkey[20];strcpy(key,node->id_number);Data_rec*pp=head;Data_rec*qq=NULL;while(pp!=NULL&&strcmp(pp->id_number,key)<0){qq=pp;pp=pp->next;}node->insert();node->ptr->next=pp;if(qq==NULL)head=node->ptr;elseqq->next=node->ptr;}voidLinkList::dele(char*id_number){Data_rec*pp=head;Data_rec*qq=NULL;while(pp!=NULL&&strcmp(pp->id_number,id_number)!=0){qq=pp;pp=pp->next;}if(pp!=NULL&&qq==NULL){head=pp->next;deletepp;}98 elseif(pp!=NULL&&qq!=NULL){qq->next=pp->next;deletepp;}}voidLinkList::print_List(){Data_rec*p=head;if(p==NULL)cout<<"nEmptyList";elsewhile(p!=NULL){p->print();p=p->next;}}Data_rec*Data_rec::ptr=NULL;intmain(){LinkListperson;Studentstudent("黄大民",21,"110105",2000,2);cout<