• 697.69 KB
  • 2022-04-22 11:32:15 发布

《c++语言程序设计》郑莉清华大学出版社课后答案

  • 192页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'课后答案网www.khdaw.com第一章概述1-1简述计算机程序设计语言的发展历程。解:迄今为止计算机程序设计语言的发展经历了机器语言、汇编语言、高级语言等阶段,C++语言是一种面向对象的编程语言,也属于高级语言。1-2面向对象的编程语言有哪些特点?解:面向对象的编程语言与以往各种编程语言有根本的不同,它设计的出发点就是为了能更直接的描述客观世界中存在的事物以及它们之间的关系。面向对象的编程语言将客观事物看作具有属性和行为的对象,通过抽象找出同一类对象的共同属性(静态特征)和行为(动态特征),形成类。通过类的继承与多态可以很方便地实现代码重用,大大缩短了软件开发周期,并使得软件风格统一。因此,面向对象的编程语言使程序能够比较直接地反问题域的本来面目,软件开发人员能够利用人类认识事物所采用的一般思维方法来进行软件开发。C++语言是目前应用最广的面向对象的编程语言。1-3什么是结构化程序设计方法?这种方法有哪些优点和缺点?解:结构化程序设计的思路是:自顶向下、逐步求精;其程序结构是按功能划分为若干个基本模块;各模块之间的关系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成;其模块化实现的具体方法是使用子程序。结构化程序设计由于采用了模块分解与功能抽象,自顶向下、分而治之的方法,从而有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。虽然结构化程序设计方法具有很多的优点,但它仍是一种面向过程的程序设计方法,它把数据和处理数据的过程分离为相互独立的实体。当数据结构改变时,所有相关的处理过程都要进行相应的修改,每一种相对于老问题的新方法都要带来额外的开销,程序的可重用性差。由于图形用户界面的应用,程序运行由顺序运行演变为事件驱动,使得软件使用起来越来越方便,但开发起来却越来越困难,对这种软件的功能很难用过程来描述和实现,使用面向过程的方法来开发和维护都将非常困难。1-4什么是对象?什么是面向对象方法?这种方法有哪些特点? 课后答案网www.khdaw.com解:从一般意义上讲,对象是现实世界中一个实际存在的事物,它可以是有形的,也可以是无形的。对象是构成世界的一个独立单位,它具有自己的静态特征和动态特征。面向对象方法中的对象,是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位,由一组属性和一组行为构成。面向对象的方法将数据及对数据的操作方法放在一起,作为一个相互依存、不可分离的整体--对象。对同类型对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口,与外界发生关系,对象与对象之间通过消息进行通讯。这样,程序模块间的关系更为简单,程序模块的独立性、数据的安全性就有了良好的保障。通过实现继承与多态性,还可以大大提高程序的可重用性,使得软件的开发和维护都更为方便。面向对象方法所强调的基本原则,就是直接面对客观存在的事物来进行软件开发,将人们在日常生活中习惯的思维方式和表达方式应用在软件开发中,使软件开发从过分专业化的方法、规则和技巧中回到客观世界,回到人们通常的思维。1-5什么叫做封装?解:封装是面向对象方法的一个重要原则,就是把对象的属性和服务结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。1-6面向对象的软件工程包括哪些主要内容?解:面向对象的软件工程是面向对象方法在软件工程领域的全面应用,它包括面向对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容。1-7简述计算机内部的信息可分为几类?解:计算机内部的信息可以分成控制信息和数据信息二大类;控制信息可分为指令和控制字两类;数据信息可分为数值信息和非数值信息两类。1-8什么叫二进制?使用二进制有何优点和缺点? 课后答案网www.khdaw.com解:二进制是基数为2,每位的权是以2为底的幂的进制,遵循逢二进一原则,基本符号为0和1。采用二进制码表示信息,有如下几个优点:1.易于物理实现;2.二进制数运算简单;3.机器可靠性高;4.通用性强。其缺点是它表示数的容量较小,表示同一个数,二进制较其他进制需要更多的位数。1-9请将以下十进制数值转换为二进制和十六进制补码:(1)2(2)9(3)93(4)-32(5)65535(6)-1解:(1)(2)10=(10)2=(2)16(2)(9)10=(1001)2=(9)16(3)(93)10=(1011101)2=(5D)16(4)(-32)10=(11100000)2=(E0)16(5)(65535)10=(1111111111111111)2=(FFFF)16(6)(-1)10=(1111111111111111)2=(FFFF)161-10请将以下数值转换为十进制:(1)(1010)2(2)(10001111)2(3)(0101111111000011)2(4)(7F)16(5)(2D3E)16(6)(F10E)16解:(1)(1010)2=(10)10(2)(10001111)2=(143)10(3)(0101111111000011)2=(24515)10(4)(7F)16=(127)10(5)(2D3E)16=(11582)10(6)(F10E)16=(61710)101-11简要比较原码、反码、补码等几种编码方法。解:原码:将符号位数字化为0或1,数的绝对值与符号一起编码,即所谓"符号──绝对值表示"的编码。正数的反码和补码与原码表示相同。负数的反码与原码有如下关系:符号位相同(仍用1表示),其余各位取反(0变1,1变0)。 课后答案网www.khdaw.com补码由该数反码的最末位加1求得。第二章C++简单程序设计2-1C++语言有那些主要特点和优点?解:C++语言的主要特点表现在两个方面,一是全面兼容C,二是支持面向对象的方法。C++是一个更好的C,它保持了C的简洁、高效、接近汇编语言、具有良好的可读性和可移植性等特点,对C的类型系统进行了改革和扩充,因此C++比C更安全,C++的编译系统能检查出更多的类型错误。C++语言最重要的特点是支持面向对象。2-2下列标识符哪些是合法的?Program,-page,_lock,test2,3in1,@mail,A_B_C_D解:Program,_lock,test2,A_B_C_D是合法的标识符,其它的不是。2-3例2.1中每条语句的作用是什么?#includevoidmain(void){cout<<"Hello!n";cout<<"Welcometoc++!n";}解:#include//指示编译器将文件iostream.h中的代码//嵌入到该程序中该指令所在的地方voidmain()//主函数名,void表示函数没有返回值{//函数体标志cout<<"Hello!n";//输出字符串Hello!到标准输出设备(显示器)上。cout<<"Welcometoc++!n";//输出字符串Welcometoc++!}在屏幕输出如下: 课后答案网www.khdaw.comHello!Welcometoc++!2-4使用关键字const而不是#define语句的好处有哪些?解:const定义的常量是有类型的,所以在使用它们时编译器可以查错;而且,这些变量在调试时仍然是可见的。2-5请写出C++语句声明一个常量PI,值为3.1416;再声明一个浮点型变量a,把PI的值赋给a。解:constfloatPI=3.1416;floata=PI;2-6在下面的枚举类型中,Blue的值是多少?enumCOLOR{WHITE,BLACK=100,RED,BLUE,GREEN=300};解:Blue=1022-7注释有什么作用?C++中有哪几种注释的方法?他们之间有什么区别?解:注释在程序中的作用是对程序进行注解和说明,以便于阅读。编译系统在对源程序进行编译时不理会注释部分,因此注释对于程序的功能实现不起任何作用。而且由于编译时忽略注释部分,所以注释内容不会增加最终产生的可执行程序的大小。适当地使用注释,能够提高程序的可读性。在C++中,有两种给出注释的方法:一种是延用C语言方法,使用"/*"和"*/"括起注释文字。另一种方法是使用"//",从"//"开始,直到它所在行的行尾,所有字符都被作为注释处理。2-8什么叫做表达式?x=5+7是一个表达式吗?它的值是多少? 课后答案网www.khdaw.com解:任何一个用于计算值的公式都可称为表达式。x=5+7是一个表达式,它的值为12。2-9下列表达式的值是多少?1.201/42.201%43.201/4.0解:1.502.13.50.252-10执行完下列语句后,a、b、c三个变量的值为多少?a=30;b=a++;c=++a;解:a:32;b:30;c:32;2-11在一个for循环中,可以初始化多个变量吗?如何实现?解:在for循环设置条件的第一个";"前,用,分隔不同的赋值表达式。例如:for(x=0,y=10;x<100;x++,y++)2-12执行完下列语句后,n的值为多少?intn;for(n=0;n<100;n++)解:n的值为100 课后答案网www.khdaw.com2-13写一条for语句,计数条件为n从100到200,步长为2;然后用while和do…while语句完成同样的循环。解:for循环:for(intn=100;n<=200;n+=2);while循环:intx=100;while(n<=200)n+=2;do…while循环:intn=100;do{n+=2;}while(n<=200);2-14if(x=3)和if(x==3)这两条语句的差别是什么?解:语句if(x=3)把3赋给x,赋值表达式的值为true,作为if语句的条件;语句if(x==3)首先判断x的值是否为3,若相等条件表达式的值为ture,否则为false。2-15什么叫做作用域?什么叫做局部变量?什么叫做全局变量,如何使用全局变量?解:作用域是一个标识符在程序正文中有效的区域。局部变量,一般来讲就是具有块作用域的变量;全局变量,就是具有文件作用域的变量。2-16已知x、y两个变量,写一条简单的if语句,把较小的的值赋给原本值较大的变量。解:if(x>y)x=y;else//y>x||y==x 课后答案网www.khdaw.comy=x;2-17修改下面这个程序中的错误,改正后它的运行结果是什么?#includevoidmain()intiintj;i=10;/*给i赋值j=20;/*给j赋值*/cout<<"i+j=<intmain(){inti;intj;i=10;//给i赋值j=20;/*给j赋值*/cout<<"i+j="<intmain(){inti;cout<<"请输入一个数字:";cin>>i;cout<<"您输入一个数字是"<intmain(){cout<<"Thesizeofanintis:tt"<intmain(){for(inti=32;i<128;i++)cout<<(char)i;return0; 课后答案网www.khdaw.com}程序运行输出:!"#$%G"()*+,./0123456789:;<>?@ABCDEFGHIJKLMNOP_QRSTUVWXYZ[]^"abcdefghijklmnopqrstuvwxyz<|>~s2-21运行下面的程序,观察其输出,与你的设想是否相同?#includeintmain(){unsignedintx;unsignedinty=100;unsignedintz=50;x=y-z;cout<<"Differenceis:"<intmain(){intmyAge=39;//initializetwointegersintyourAge=39;cout<<"Iam:"<5)||(6<2)解:1.true2.false3.true2-26若a=1,b=2,c=3,下列各式的结果是什么?1.a|b-c2.a^b&-c3.a&b|c4.a|b&c解:1.-12.13.34.32-27若a=1,下列各式的结果是什么?1.!a|a2.~a|a3.a^a4.a>>2解:1.12.-13.04.02-28编写一个完整的程序,实现功能:向用户提问"现在正在下雨吗?",提示用户输入Y或N。若输入为Y,显示"现在正在下雨。";若输入为N,显示"现在没有下雨。";否则继续提问"现在正在下雨吗?" 课后答案网www.khdaw.com解:源程序:#include#includevoidmain(){charflag;while(1){cout<<"现在正在下雨吗?(YesorNo):";cin>>flag;if(toupper(flag)=="Y"){cout<<"现在正在下雨。";break;}if(toupper(flag)=="N"){cout<<"现在没有下雨。";break;}}}程序运行输出:现在正在下雨吗?(YesorNo):x现在正在下雨吗?(YesorNo):l现在正在下雨吗?(YesorNo):q现在正在下雨吗?(YesorNo):n现在没有下雨。或:现在正在下雨吗?(YesorNo):y现在正在下雨。2-29编写一个完整的程序,运行时向用户提问"你考试考了多少分?(0~100)",接收输入后判断其等级,显示出来。规则如下:解:#include 课后答案网www.khdaw.comvoidmain(){inti,score;cout<<"你考试考了多少分?(0~100):";cin>>score;if(score>100||score<0)cout<<"分数值必须在0到100之间!";else{i=score/10;switch(i){case10:case9:cout<<"你的成绩为优!";break;case8:cout<<"你的成绩为良!";break;case7:case6:cout<<"你的成绩为中!";break;default:cout<<"你的成绩为差!";}}}程序运行输出:你考试考了多少分?(0~100):85你的成绩为良!2-30(1)实现一个简单的菜单程序,运行时显示"Menu:A(dd)D(elete)S(ort)Q(uit),Selectone:"提示用户输入,A表示增加,D表示删除,S表示排序,Q表示退出,输入为A、D、S时分别提示"数据已经增加、删除、排序。"输入为Q时程序结束。要求使用if…else语句进行判断,用break、continue控制程序流程。解:#include#include 课后答案网www.khdaw.comvoidmain(){charchoice,c;while(1){cout<<"Menu:A(dd)D(elete)S(ort)Q(uit),Selectone:";cin>>c;choice=toupper(c);if(choice=="A"){cout<<"数据已经增加."<#include 课后答案网www.khdaw.comvoidmain(){charchoice;while(1){cout<<"Menu:A(dd)D(elete)S(ort)Q(uit),Selectone:";cin>>choice;switch(toupper(choice)){case"A":cout<<"数据已经增加."<#includevoidmain(){inti,j,k,flag;i=2;while(i<=100){flag=1;k=sqrt(i);j=2;while(j<=k){if(i%j==0){flag=0;break;}j++;}if(flag)cout<#includevoidmain(){inti,j,k,flag;i=2;do{flag=1;k=sqrt(i);j=2;do{if(i%j==0){flag=0;break; 课后答案网www.khdaw.com}j++;}while(j<=k);if(flag)cout<#includevoidmain(){inti,j,k,flag;for(i=2;i<=100;i++){flag=1;k=sqrt(i);for(j=2;j<=k;j++){if(i%j==0){flag=0;break;}}if(flag)cout<voidmain(){intn=18;intm=0; 课后答案网www.khdaw.comwhile(m!=n){cout<<"请猜这个数的值为多少?(0~~100):";cin>>m;if(n>m)cout<<"你猜的值太小了!"<voidmain(){intn=18;intm=0;do{cout<<"请猜这个数的值为多少?(0~~100):";cin>>m;if(n>m)cout<<"你猜的值太小了!"<enumweekday{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};voidmain(){inti;weekdayd=Thursday;cout<<"d="<intmain(){intintOne;int&rSomeRef=intOne;intOne=5;cout<<"intOne:tt"< 课后答案网www.khdaw.comshortintDivider(unsignedshortinta,unsignedshortintb){if(b==0)return-1;elsereturna/b;}typedefunsignedshortintUSHORT;typedefunsignedlongintULONG;intmain(){USHORTone,two;shortintanswer;cout<<"Entertwonumbers.nNumberone:";cin>>one;cout<<"Numbertwo:";cin>>two;answer=Divider(one,two);if(answer>-1)cout<<"Answer:"<#includeintprime(inti);//判一个数是否是质数的函数voidmain(){inti;cout<<"请输入一个整数:";cin>>i;if(prime(i))cout< 课后答案网www.khdaw.com#includeintfn1(inti,intj);//求最大公约数的函数voidmain(){inti,j,x,y;cout<<"请输入一个正整数:";cin>>i;cout<<"请输入另一个正整数:";cin>>j;x=fn1(i,j);y=i*j/x;cout<#includeintfn1(inti);voidmain(){inti;cout<<"请输入一个正整数:";cin>>i;cout<<"从1累加到"<longGetPower(intx,inty); 课后答案网www.khdaw.comintmain(){intnumber,power;longanswer;cout<<"Enteranumber:";cin>>number;cout<<"Towhatpower?";cin>>power;answer=GetPower(number,power);cout<2;fib(1)=fib(2)=1;观察递归调用的过程。解:源程序见"实验指导"部分实验三3-15用递归的方法编写函数求n阶勒让德多项式的值,在主程序中实现输入、输出;解:#includefloatp(intn,intx);voidmain(){intn,x; 课后答案网www.khdaw.comcout<<"请输入正整数n:";cin>>n;cout<<"请输入正整数x:";cin>>x;cout<<"n="<templatevoidswap(T&x,T&y){Tz;z=x; 课后答案网www.khdaw.comx=y;y=z;}voidmain(){intj=1,k=2;doublev=3.0,w=4.0;cout<<"j="<classRectangle{public:Rectangle(inttop,intleft,intbottom,intright);~Rectangle(){}intGetTop()const{returnitsTop;}intGetLeft()const{returnitsLeft;}intGetBottom()const{returnitsBottom;}intGetRight()const{returnitsRight;}voidSetTop(inttop){itsTop=top;}voidSetLeft(intleft){itsLeft=left;}voidSetBottom(intbottom){itsBottom=bottom;}voidSetRight(intright){itsRight=right;}intGetArea()const;private:intitsTop;intitsLeft;intitsBottom;intitsRight;};Rectangle::Rectangle(inttop,intleft,intbottom,intright){itsTop=top; 课后答案网www.khdaw.comitsLeft=left;itsBottom=bottom;itsRight=right;}intRectangle::GetArea()const{intWidth=itsRight-itsLeft;intHeight=itsTop-itsBottom;return(Width*Height);}intmain(){RectangleMyRectangle(100,20,50,80);intArea=MyRectangle.GetArea();cout<<"Area:"<classRectangle 课后答案网www.khdaw.com{public:Rectangle(floatlen,floatwidth){Length=len;Width=width;}~Rectangle(){};floatGetArea(){returnLength*Width;}floatGetLength(){returnLength;}floatGetWidth(){returnWidth;}private:floatLength;floatWidth;};voidmain(){floatlength,width;cout<<"请输入矩形的长度:";cin>>length;cout<<"请输入矩形的宽度:";cin>>width;Rectangler(length,width);cout<<"长为"<classdatatype{enum{character, 课后答案网www.khdaw.cominteger,floating_point}vartype;union{charc;inti;floatf;};public:datatype(charch){vartype=character;c=ch;}datatype(intii){vartype=integer;i=ii;}datatype(floatff){vartype=floating_point;f=ff;}voidprint();};voiddatatype::print(){switch(vartype){casecharacter:cout<<"字符型:"<classCircle{public:Circle(floatradius){Radius=radius;}~Circle(){}floatGetArea(){return3.14*Radius*Radius;}private:floatRadius;};voidmain(){floatradius;cout<<"请输入圆的半径:";cin>>radius;Circlep(radius);cout<<"半径为"<classTree{intages;public:Tree(intn=0);~Tree();voidgrow(intyears);voidage();};Tree::Tree(intn){ages=n;}Tree::~Tree(){age();}voidTree::grow(intyears){ages+=years;}voidTree::age(){cout<<"这棵树的年龄为"<voidmyFunction();intx=5,y=7;intmain(){cout<<"xfrommain:"<classCat{public:Cat(intage):itsAge(age){HowManyCats++;}virtual~Cat(){HowManyCats--;}virtualintGetAge(){returnitsAge;}virtualvoidSetAge(intage){itsAge=age;}staticintGetHowMany(){returnHowManyCats;}private:intitsAge; 课后答案网www.khdaw.comstaticintHowManyCats;};intCat::HowManyCats=0;voidTelepathicFunction();intmain(){constintMaxCats=5;Cat*CatHouse[MaxCats];inti;for(i=0;i#include"fn1.h"intn;voidmain(){n=20;fn1();cout<<"n的值为"<voidfn1(){staticintn=0;n++;cout<<"n的值为"<i=+10;}voidY::g(X*x){x->i++;}classZ{public:voidf(X*x){x->i+=5;}}; 课后答案网www.khdaw.com#endif//MY_X_Y_Z_H程序运行输出:无5-14定义Boat与Car两个类,二者都有weight属性,定义二者的一个友元函数totalWeight(),计算二者的重量和。解:源程序:#includeclassBoat;classCar{private:intweight;public:Car(intj){weight=j;}friendinttotalWeight(Car&aCar,Boat&aBoat);};classBoat{private:intweight;public:Boat(intj){weight=j;}friendinttotalWeight(Car&aCar,Boat&aBoat);};inttotalWeight(Car&aCar,Boat&aBoat){returnaCar.weight+aBoat.weight;}voidmain(){Carc1(4);Boatb1(5);cout<intmain(){intmyArray[5];inti;for(i=0;i<5;i++){cout<<"ValueformyArray["<>myArray[i];}for(i=0;i<5;i++)cout<intmain(){int*p;*pInt=9;cout<<"Thevalueatp:"<<*p;return0;}解:指针p没有初始化,也就是没有指向某个确定的内存单元,它指向内存中的一个随机地址,给这个随机地址赋值是非常危险的。6-18下列程序有何问题,请改正;仔细体会使用指针时应避免出现的这个问题。#includeintFn1();intmain(){inta=Fn1();cout<<"thevalueofais:"<int*Fn1();intmain(){int*a=Fn1();cout<<"thevalueofais:"<<*a;deletea;return0;} 课后答案网www.khdaw.comint*Fn1(){int*p=newint(5);returnp;}6-19声明一个参数为整型,返回值为长整型的函数指针;声明类A的一个成员函数指针,其参数为整型,返回值长整型。解:long(*p_fn1)(int);long(A::*p_fn2)(int);6-20实现一个名为SimpleCircle的简单圆类,其数据成员int*itsRadius为一个指向其半径值的指针,设计对数据成员的各种操作,给出这个类的完整实现并测试这个类。解:源程序:#includeclassSimpleCircle{public:SimpleCircle();SimpleCircle(int);SimpleCircle(constSimpleCircle&);~SimpleCircle(){}voidSetRadius(int);intGetRadius()const;private:int*itsRadius;};SimpleCircle::SimpleCircle(){itsRadius=newint(5);} 课后答案网www.khdaw.comSimpleCircle::SimpleCircle(intradius){itsRadius=newint(radius);}SimpleCircle::SimpleCircle(constSimpleCircle&rhs){intval=rhs.GetRadius();itsRadius=newint(val);}intSimpleCircle::GetRadius()const{return*itsRadius;}intmain(){SimpleCircleCircleOne,CircleTwo(9);cout<<"CircleOne:"<#includeintcount(char*str){inti,num=0;for(i=0;str[i];i++){if((str[i]>="a"&&str[i]<="z")||(str[i]>="A"&&str[i]<="Z"))num++;}returnnum;} 课后答案网www.khdaw.comvoidmain(){chartext[100];cout<<"输入一个英语句子:"<intindex(char*s,char*t){inti,j,k;for(i=0;s[i]!="";i++){for(j=i,k=0;t[k]!=""&&s[j]==t[k];j++,k++);if(t[k]=="")returni;}return-1;}voidmain(){intn;charstr1[20],str2[20];cout<<"输入一个英语单词:";cin>>str1;cout<<"输入另一个英语单词:";cin>>str2; 课后答案网www.khdaw.comn=index(str1,str2);if(n>0)cout<#includevoidreverse(char*s,char*t){charc;if(s>str1;cout<<"原字符串为:"<#include#defineN8floatgrades[N];//存放成绩的数组voidmain(){inti;floattotal,average;//提示输入成绩for(i=0;i>grades[i];}total=0;for(i=0;i#includeclassMyString{public:MyString();MyString(constchar*const);MyString(constMyString&);~MyString();char&operator[](unsignedshortoffset);charoperator[](unsignedshortoffset)const;MyStringoperator+(constMyString&);voidoperator+=(constMyString&);MyString&operator=(constMyString&);unsignedshortGetLen()const{returnitsLen;}constchar*GetMyString()const{returnitsMyString;}private:MyString(unsignedshort);//privateconstructorchar*itsMyString;unsignedshortitsLen;};MyString::MyString(){itsMyString=newchar[1];itsMyString[0]="";itsLen=0;} 课后答案网www.khdaw.comMyString::MyString(unsignedshortlen){itsMyString=newchar[len+1];for(unsignedshorti=0;i<=len;i++)itsMyString[i]="";itsLen=len;}MyString::MyString(constchar*constcMyString){itsLen=strlen(cMyString);itsMyString=newchar[itsLen+1];for(unsignedshorti=0;iitsLen)returnitsMyString[itsLen-1];elsereturnitsMyString[offset];}charMyString::operator[](unsignedshortoffset)const{if(offset>itsLen)returnitsMyString[itsLen-1];elsereturnitsMyString[offset];}MyStringMyString::operator+(constMyString&rhs){unsignedshorttotalLen=itsLen+rhs.GetLen();MyStringtemp(totalLen);for(unsignedshorti=0;ivoidmove(intmatrix[3][3]){inti,j,k;for(i=0;i<3;i++)for(j=0;j>data[i][j];}cout<<"输入的矩阵的为:"<voidmove(int*matrix,intn){inti,j,k;for(i=0;i>n;p=newint[n*n];cout<<"输入矩阵的元素"<>p[i*n+j];}cout<<"输入的矩阵的为:"<#includeclassEmployee{private:charname[30];charstreet[30];charcity[18];charzip[6];public:Employee(char*n,char*str,char*ct,char*z);voidchange_name(char*n);voiddisplay();};Employee::Employee(char*n,char*str,char*ct,char*z){strcpy(name,n);strcpy(street,str);strcpy(city,ct);strcpy(zip,z);}voidEmployee::change_name(char*n){strcpy(name,n);}voidEmployee::display() 课后答案网www.khdaw.com{cout<classShape{public:Shape(){}~Shape(){}virtualfloatGetArea(){return-1;}};classCircle:publicShape{public: 课后答案网www.khdaw.comCircle(floatradius):itsRadius(radius){}~Circle(){}floatGetArea(){return3.14*itsRadius*itsRadius;}private:floatitsRadius;};classRectangle:publicShape{public:Rectangle(floatlen,floatwidth):itsLength(len),itsWidth(width){};~Rectangle(){};virtualfloatGetArea(){returnitsLength*itsWidth;}virtualfloatGetLength(){returnitsLength;}virtualfloatGetWidth(){returnitsWidth;}private:floatitsWidth;floatitsLength;};classSquare:publicRectangle{public:Square(floatlen);~Square(){}};Square::Square(floatlen):Rectangle(len,len){}voidmain(){Shape*sp;sp=newCircle(5);cout<<"TheareaoftheCircleis"<GetArea()<GetArea()<GetArea()<enummyColor{BLACK,WHITE};classMammal{public://constructorsMammal();~Mammal();//accessorsintGetAge()const{returnitsAge;}voidSetAge(intage){itsAge=age;}intGetWeight()const{returnitsWeight;}voidSetWeight(intweight){itsWeight=weight;}//OthermethodsvoidSpeak()const{cout<<"Mammalsound!n";}protected:intitsAge;intitsWeight;};classDog:publicMammal{public:Dog();~Dog(); 课后答案网www.khdaw.commyColorGetColor()const{returnitsColor;}voidSetColor(myColorcolor){itsColor=color;}voidWagTail(){cout<<"Tailwagging...n";}private:myColoritsColor;};Mammal::Mammal():itsAge(1),itsWeight(5){cout<<"Mammalconstructor...n";}Mammal::~Mammal(){cout<<"Mammaldestructor...n";}Dog::Dog():itsColor(WHITE){cout<<"Dogconstructor...n";}Dog::~Dog(){cout<<"Dogdestructor...n";}intmain(){DogJack;Jack.Speak();Jack.WagTail();cout<<"Jackis"<classBaseClass{public:BaseClass();};BaseClass::BaseClass(){cout<<"构造基类对象!"<#includeclassDocument{public:Document(){};Document(char*name);char*Name;//Documentname.voidPrintNameOf();//Printname.};Document::Document(char*name){Name=newchar[strlen(name)+1];strcpy(Name,name);};voidDocument::PrintNameOf(){cout<classobject{private:intWeight;public:object(){cout<<"构造object对象"<classBaseClass{public:voidfn1();voidfn2();};voidBaseClass::fn1(){cout<<"调用基类的函数fn1()"<fn1();pBaseClass->fn2();pDerivedClass->fn1();pDerivedClass->fn2();}程序运行输出:调用派生类的函数fn1()调用派生类的函数fn2()调用基类的函数fn1()调用基类的函数fn2()调用派生类的函数fn1()调用派生类的函数fn2()7-12为例9-1的吹泡泡程序加一版权(About)对话框。然后修改例9-1的程序,加入以下内容:程序:1.在程序首部加上文件包含命令#include“resource.h”2.在框架窗口类之前加入从CDialog类派生的对话框类://对话框类classCAboutDlg:publicCDialog{public:CAboutDlg();enum{IDD=IDD_DIALOG1};};inlineCAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){}3.在框架窗口类中添加响应鼠标右键消息的代码,包括消息响应函数说明、消息响应宏和消息响应函数定义。鼠标右键消息响应函数为:voidCMyWnd::OnRButtonDown(UINTnFlags,CPointpoint) 课后答案网www.khdaw.com{CAboutDlgdlg;dlg.DoModal();}7-13签名留念簿程序。该程序模仿签名簿,用户使用鼠标左键点击窗口客户区后会弹出一个对话框,输入姓名后可在鼠标点击位置显示出该签名。签名的颜色、字体大小和方向随机确定。说明:项目建立及添加对话框模板资源的方法同例14-1。修改对话框模板的ID为IDD_NAMEDLG,Caption为“签名对话框”,并添加一个静态文本控件(Caption改为“签名”)和一个编辑控件(ID改为IDC_EDITNAME)。程序://Example14-2:签名留念簿程序#include#include"resource.h"//对话框类classCNameDlg:publicCDialog{public:CPointm_pointTopLeft;CStringm_strNameEdit;public:CNameDlg();enum{IDD=IDD_NAMEDLG};protected:virtualvoidDoDataExchange(CDataExchange*pDX);virtualBOOLOnInitDialog();};//对话框类的构造函数CNameDlg::CNameDlg():CDialog(CNameDlg::IDD){m_strNameEdit=_T("");}//数据交换和数据检验voidCNameDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);DDX_Text(pDX,IDC_EDITNAME,m_strNameEdit);DDV_MaxChars(pDX,m_strNameEdit,20);}//初始化对话框BOOLCNameDlg::OnInitDialog() 课后答案网www.khdaw.com{CDialog::OnInitDialog();CRectrect;GetWindowRect(&rect);rect=CRect(m_pointTopLeft,rect.Size());MoveWindow(rect);returnTRUE;}//签名类classCSignal:publicCObject{CStringm_sName;//姓名CPointm_pointSignal;//签名位置intm_nHeight;//字体高intm_nColor;//签名颜色intm_nEscapement;//签名倾角public:CSignal(){}voidSetValue(CStringname,CPointpoint,intheight,intcolor,intescapement);voidShowSignal(CDC*pDC);};//签名类成员函数voidCSignal::SetValue(CStringname,CPointpoint,intheight,intcolor,intescapement){m_sName=name;m_pointSignal=point;m_nHeight=height;m_nColor=color;m_nEscapement=escapement;}//显示签名voidCSignal::ShowSignal(CDC*pDC){CFont*pOldFont,font;font.CreateFont(m_nHeight,0,m_nEscapement,0,400,FALSE,FALSE,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"楷体");pOldFont=pDC->SelectObject(&font);switch(m_nColor){case0: 课后答案网www.khdaw.compDC->SetTextColor(RGB(0,0,0));break;case1:pDC->SetTextColor(RGB(255,0,0));break;case2:pDC->SetTextColor(RGB(0,255,0));break;case3:pDC->SetTextColor(RGB(0,0,255));break;}pDC->TextOut(m_pointSignal.x,m_pointSignal.y,m_sName);pDC->SelectObject(pOldFont);}//框架窗口类#defineMAX_NAME250classCMyWnd:publicCFrameWnd{CSignalm_signalList[MAX_NAME];intm_nCount;public:CMyWnd():m_nCount(0){}protected:afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_PAINT()END_MESSAGE_MAP()//框架窗口类的成员函数//鼠标右键消息响应函数voidCMyWnd::OnLButtonDown(UINTnFlags,CPointpoint){if(m_nCountCreate(0,_T("签字留念簿程序"));pFrame->ShowWindow(m_nCmdShow);this->m_pMainWnd=pFrame;returnTRUE;}//全局应用程序对象CMyAppThisApp;7-14将例14-2的签名留念簿中的对话框改为无模式对话框。用户可用鼠标右键调出签名对话框,并在不退出该对话框的情况下用鼠标左键将输入的签名显示在窗口客户区。说明:在向项目中添加对话框模板资源时,要在其属性对话框的MoreStyles页中选择Visible项。其他同例14-2。程序: 课后答案网www.khdaw.com该程序中的签名类CSignal和应用程序类与上例相同,因此下面仅列出了框架窗口类和对话框类。由于这两个类的成员函数中存在相互引用的情况,所以我们将框架窗口类的声明放在前面,接下来是对话框类的定义,并在框架窗口类之前加入了一条对对话框类的声明。最后是这两个类的成员函数定义。//框架窗口类#defineMAX_NAME250classCNameDlg;classCMyWnd:publicCFrameWnd{CSignalm_signalList[MAX_NAME];intm_nCount;CNameDlg*m_pNameDlg;public:CMyWnd();~CMyWnd();protected:afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnRButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP()};//对话框类classCNameDlg:publicCDialog{public:BOOLm_bActive;CStringm_strNameEdit;enum{IDD=IDD_NAMEDLG};CNameDlg();BOOLCreate();protected:virtualvoidDoDataExchange(CDataExchange*pDX);virtualBOOLOnInitDialog();virtualvoidOnOK();virtualvoidOnCancel();};//框架窗口类的消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_RBUTTONDOWN()ON_WM_PAINT()END_MESSAGE_MAP()//框架窗口类的成员函数 课后答案网www.khdaw.com//框架窗口类的构造函数CMyWnd::CMyWnd(){m_nCount=0;m_pNameDlg=newCNameDlg;}//框架窗口类的析构函数CMyWnd::~CMyWnd(){deletem_pNameDlg;}//鼠标右键消息响应函数voidCMyWnd::OnRButtonDown(UINTnFlags,CPointpoint){if(m_pNameDlg->m_bActive)m_pNameDlg->SetActiveWindow();//激活对话框elsem_pNameDlg->Create();//显示对话框}//鼠标左键消息响应函数voidCMyWnd::OnLButtonDown(UINTnFlags,CPointpoint){if(m_nCountm_strNameEdit;m_signalList[m_nCount].SetValue(name,point,height,color,escapement);m_nCount++;Invalidate();}}//绘制框架窗口客户区函数voidCMyWnd::OnPaint(){CPaintDCdc(this);for(inti=0;i#include#include#include"resource.h"//对话框类classCNameDlg:publicCDialog{public:CPointm_pointTopLeft;//对话框位置CStringm_strNameEdit;//签名LONGm_lEscapement;//签名倾角public:CNameDlg();enum{IDD=IDD_NAMEDLG};protected:virtualvoidDoDataExchange(CDataExchange*pDX);virtualBOOLOnInitDialog();};//对话框类的构造函数CNameDlg::CNameDlg():CDialog(CNameDlg::IDD),m_pointTopLeft(0,0){m_strNameEdit=_T("");m_lEscapement=0;}//数据交换和数据检验voidCNameDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);DDX_Text(pDX,IDC_EDIT1,m_strNameEdit);DDX_Text(pDX,IDC_EDIT2,m_lEscapement);DDV_MaxChars(pDX,m_strNameEdit,20);DDV_MinMaxLong(pDX,m_lEscapement,-600,600);}//初始化对话框BOOLCNameDlg::OnInitDialog(){CDialog::OnInitDialog();CRectrect;GetWindowRect(&rect);rect=CRect(m_pointTopLeft,rect.Size()); 课后答案网www.khdaw.comMoveWindow(rect);returnTRUE;}//签名类classCSignal:publicCObject{CStringm_strSignal;//姓名COLORREFm_colorSignal;//签名颜色CPointm_pointSignal;//签名位置LOGFONTm_fontSignal;//签名字体public:CSignal(){}voidSetValue(CStringsignal,CPointpoint,COLORREFcolor,LONGescapement,LOGFONT*pfont);voidShowSignal(CDC*pDC);};//签名类成员函数voidCSignal::SetValue(CStringsignal,CPointpoint,COLORREFcolor,intescapement,LOGFONT*pfont){m_strSignal=signal;m_pointSignal=point;m_colorSignal=color;memcpy(&m_fontSignal,pfont,sizeof(LOGFONT));m_fontSignal.lfEscapement=escapement;}//显示签名voidCSignal::ShowSignal(CDC*pDC){CFontfont,*pOldFont;font.CreateFontIndirect(&m_fontSignal);pOldFont=pDC->SelectObject(&font);pDC->SetTextColor(m_colorSignal);pDC->TextOut(m_pointSignal.x,m_pointSignal.y,m_strSignal);pDC->SelectObject(pOldFont);}//框架窗口类#defineMAX_NAME250classCMyWnd:publicCFrameWnd{CSignalm_signalList[MAX_NAME];//签名数组intm_nCount;//签名数量LOGFONTm_fontSignal;//签名字体COLORREFm_colorSignal;//签名颜色 课后答案网www.khdaw.compublic:CMyWnd();protected:afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnRButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_RBUTTONDOWN()ON_WM_PAINT()END_MESSAGE_MAP()//框架窗口类的成员函数CMyWnd::CMyWnd(){m_nCount=0;m_colorSignal=RGB(0,0,0);m_fontSignal.lfHeight=40;m_fontSignal.lfWidth=0;m_fontSignal.lfEscapement=0;m_fontSignal.lfOrientation=0;m_fontSignal.lfWeight=400;m_fontSignal.lfItalic=FALSE;m_fontSignal.lfUnderline=FALSE;m_fontSignal.lfStrikeOut=0;m_fontSignal.lfCharSet=OEM_CHARSET;m_fontSignal.lfOutPrecision=OUT_DEFAULT_PRECIS;m_fontSignal.lfClipPrecision=CLIP_DEFAULT_PRECIS;m_fontSignal.lfQuality=DEFAULT_QUALITY;m_fontSignal.lfPitchAndFamily=DEFAULT_PITCH;strcpy(m_fontSignal.lfFaceName,"Arial");}//鼠标右键消息响应函数voidCMyWnd::OnLButtonDown(UINTnFlags,CPointpoint){if(m_nCountCreate(0,_T("签字留念簿程序"));pFrame->ShowWindow(SW_SHOWMAXIMIZED);this->m_pMainWnd=pFrame;returnTRUE;}//全局应用程序对象CMyAppThisApp; 课后答案网www.khdaw.com7-16为例9-3的吹泡泡程序添加颜色选择对话框,使其可以绘出五颜六色的泡泡。程序:在例9-3的程序基础上作如下修改:1.在程序首部添加文件包含命令:#include2.在框架窗口类声明中添加一个COLORREF类型的数组,存放各泡泡的颜色:COLORREFm_colorBubble[MAX_BUBBLE];3.修改鼠标左键消息映射函数,添加使用颜色选择公用对话框的代码:voidCMyWnd::OnLButtonDown(UINTnFlags,CPointpoint){if(m_nBubbleCount>m_nBubbleCount;for(inti=0;i>m_rectBubble[i];}}7-18修改例12-1的程序并观察其打印结果。程序:在例12-1程序的视图类CMyView类的成员函数OnDraw()中,添加代码沿窗口客户区轮廓画一矩形:voidCMyView::OnDraw(CDC*pDC){CRectrect;GetClientRect(&rect);pDC->Rectangle(rect);CMyDoc*pDoc=GetDocument();//取文档指针ASSERT_VALID(pDoc);pDC->SelectStockObject(LTGRAY_BRUSH);//在视图上显示文档数据for(inti=0;iGetListSize();i++)pDC->Ellipse(pDoc->GetBubble(i));} 课后答案网www.khdaw.com7-19改进吹泡泡程序,使之打印输出与屏幕显示的比例相近。程序:在例12-1基础上修改。首先在CMyView类中重载虚函数OnPrepareDC()。在CMyView类的声明中增加一行:virtualvoidOnPrepareDC(CDC*pDC,CPrintInfo*pInfo=NULL);然后添加该函数的定义,设置映射模式为MM_LOMETRIC://设置映射模式voidCMyView::OnPrepareDC(CDC*pDC,CPrintInfo*pInfo){pDC->SetMapMode(MM_LOMETRIC);CView::OnPrepareDC(pDC,pInfo);}然后修改消息映射函数OnLButtonDown(),将物理坐标转换为逻辑坐标://响应点击鼠标左键消息voidCMyView::OnLButtonDown(UINTnFlags,CPointpoint){CMyDoc*pDoc=GetDocument();//取文档指针ASSERT_VALID(pDoc);CClientDCdc(this);//设置设备环境OnPrepareDC(&dc);intr=rand()%50+5;//生成泡泡CRectrect(point.x-r,point.y-r,point.x+r,point.y+r);InvalidateRect(rect,FALSE);//更新视图dc.DPtoLP(rect);//转换物理坐标为逻辑坐标pDoc->AddBubble(rect);//修改文档数据pDoc->SetModifiedFlag();//设置修改标志}7-20声明一个Person类,并使之支持序列化。程序:classCPerson:publicCObject{DECLARE_SERIAL(CPerson)LONGm_IDnumber;//身份证号码CStringm_strName;//姓名CStringm_strNation;//民族 课后答案网www.khdaw.comintm_nSex;//性别intm_nAge;//年龄BOOLm_bMarried;//婚否public:CEmployee(){};CPerson&operator=(CPerson&person);voidSerialize(CArchive&ar);};IMPLEMENT_SERIAL(CPerson,CObject,1)CPerson&CPerson::operator=(CPerson&person){m_IDnumber=person.m_IDnumber;m_strName=person.m_strName;m_strNation=person.m_strNation;m_nSex=person.m_nSex;m_nAge=person.m_nAge;m_bMarried=person.m_bMarried;return*this;}voidCPerson::Serialize(CArchive&ar){CObject::Serialize(ar);//首先调用基类的Serialize()方法if(ar.IsStoring()){ar<>m_IDnumber;ar>>m_strName;ar>>m_strNation;ar>>m_nSex;ar>>m_nAge;ar>>(int)m_bMarried;}}7-21修改例13-3的吹泡泡程序,使其打印每个泡泡的数据值。打印格式为每页40行,页眉为文档名,页脚为页号。 课后答案网www.khdaw.com说明:首先为视图类添加一个数据成员m_nLinePerPage,用来存放每页行数,并在视图类CMyView的构造函数中将m_nLinePerPage初始化为40。修改视图类成员函数OnPrepareDC(),设置映射模式为MM_TWIPS。该模式为每英寸1440点,很适合打印机输出。程序:重载视图类的成员函数OnPreparePrinting(),在其中添加计算打印页数的代码:BOOLCMyView::OnPreparePrinting(CPrintInfo*pInfo){CMyDoc*pDoc=GetDocument();intnPageCount=pDoc->GetListSize()/m_nLinePerPage;if(pDoc->GetListSize()%m_nLinePerPage)nPageCount++;pInfo->SetMaxPage(nPageCount);returnDoPreparePrinting(pInfo);}最后重载视图类的OnPrint()函数并添加打印代码:voidCMyView::OnPrint(CDC*pDC,CPrintInfo*pInfo){intnPage=pInfo->m_nCurPage;//当前页号intnStart=(nPage-1)*m_nLinePerPage;//本页第一行intnEnd=nStart+m_nLinePerPage;//本页最后一行CFontfont;//设置字体font.CreateFont(-280,0,0,0,400,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_MODERN,"CourierNew");CFont*pOldFont=(CFont*)(pDC->SelectObject(&font));CRectrectPaper=pInfo->m_rectDraw;//取页面打印矩形//页眉:页面顶端中央打印文档名称CMyDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);CStringstr;str.Format("BubbleReport:%s",(LPCSTR)pDoc->GetTitle());CSizesizeText=pDC->GetTextExtent(str);CPointpoint((rectPaper.Width()-sizeText.cx)/2,0);pDC->TextOut(point.x,point.y,str);point.x=rectPaper.left;//打印页眉下划线point.y=rectPaper.top-sizeText.cy;pDC->MoveTo(point);point.x=rectPaper.right;pDC->LineTo(point); 课后答案网www.khdaw.com//打印表头str.Format("%6.6s%6.6s%6.6s%6.6s%6.6s","Index","Left","Top","Right","Bottom");point.x=720;point.y-=720;pDC->TextOut(point.x,point.y,str);TEXTMETRICtm;//取当前字体有关信息pDC->GetTextMetrics(&tm);intnHeight=tm.tmHeight+tm.tmExternalLeading;point.y-=360;//下移1/4英寸for(inti=nStart;i=pDoc->GetListSize())break;str.Format("%6d%6d%6d%6d%6d",i+1,pDoc->GetBubble(i).left,pDoc->GetBubble(i).top,pDoc->GetBubble(i).right,pDoc->GetBubble(i).bottom);point.y-=nHeight;pDC->TextOut(point.x,point.y,str);}//在页面底部中央打印页号str.Format("-%d-",nPage);sizeText=pDC->GetTextExtent(str);point.x=(rectPaper.Width()-sizeText.cx)/2;point.y=rectPaper.Height()+sizeText.cy;pDC->TextOut(point.x,point.y,str);//释放字体对象pDC->SelectObject(pOldFont);}7-22修改例11-4的拼图程序,使之在难度菜单的相应选项前打钩。程序:首先在框架窗口类的消息响应函数声明处增加以下消息响应函数的声明:afx_msgvoidCPuzzleWnd::OnUpdateGrad01(CCmdUI*pCmdUI);afx_msgvoidCPuzzleWnd::OnUpdateGrad02(CCmdUI*pCmdUI);afx_msgvoidCPuzzleWnd::OnUpdateGrad03(CCmdUI*pCmdUI);然后在框架窗口类的消息映射宏中加入相应内容: 课后答案网www.khdaw.comBEGIN_MESSAGE_MAP(CPuzzleWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_WM_PAINT()ON_COMMAND(ID_SHOWFIG,OnShowFig)ON_COMMAND(ID_GRAD01,OnGrad01)ON_COMMAND(ID_GRAD02,OnGrad02)ON_COMMAND(ID_GRAD03,OnGrad03)ON_UPDATE_COMMAND_UI(ID_GRAD01,OnUpdateGrad01)ON_UPDATE_COMMAND_UI(ID_GRAD02,OnUpdateGrad02)ON_UPDATE_COMMAND_UI(ID_GRAD03,OnUpdateGrad03)END_MESSAGE_MAP()注意更新命令用户接口消息映射宏将菜单标识符与相应的消息映射函数联系在一起。最后编写相应的更新命令用户接口消息映射函数:voidCPuzzleWnd::OnUpdateGrad01(CCmdUI*pCmdUI){pCmdUI->SetCheck(m_nColCount==4);}voidCPuzzleWnd::OnUpdateGrad02(CCmdUI*pCmdUI){pCmdUI->SetCheck(m_nColCount==8);}voidCPuzzleWnd::OnUpdateGrad03(CCmdUI*pCmdUI){pCmdUI->SetCheck(m_nColCount==16);}输入输出:在选择拼图难度时,可在相应选项前打钩(图13-4)。//Example13-7:七巧板程序//////////////////////////////////#include#include//拼板类////////////////////////////////////////////////////#defineMAX_POINTS4#defineCHIP_WIDTH240#defineDELTA30classCChip:publicCObject{DECLARE_SERIAL(CChip)intm_nType;CPointm_pointList[MAX_POINTS];intm_nPointCount;public: 课后答案网www.khdaw.comCChip(){}voidSetChip(inttype,POINT*ppointlist,intcount);voidDrawChip(CDC*pDC);BOOLPtInChip(POINTpoint);LPCRECTGetRect();voidMoveTo(CSizeoffset);voidRotation();voidSerialize(CArchive&ar);};IMPLEMENT_SERIAL(CChip,CObject,1)//设置拼图块参数voidCChip::SetChip(inttype,POINT*ppointlist,intcount){m_nType=type;m_nPointCount=count;for(inti=0;iSelectObject(&penNew);pbrushOld=pDC->SelectObject(&brushNew);pDC->Polygon(m_pointList,m_nPointCount);pDC->SelectObject(ppenOld);pDC->SelectObject(pbrushOld);}//检测一点是否在拼图块中BOOLCChip::PtInChip(POINTpoint){CRgnrgn;rgn.CreatePolygonRgn(m_pointList,m_nPointCount,0);returnrgn.PtInRegion(point);}//取拼图块的包含矩形LPCRECTCChip::GetRect(){staticRECTrect;CRgnrgn;rgn.CreatePolygonRgn(m_pointList,m_nPointCount,0);rgn.GetRgnBox(&rect);rect.right++;rect.bottom++;return▭}//旋转拼图块voidCChip::Rotation(){CRectrect;CRgnrgn;rgn.CreatePolygonRgn(m_pointList,m_nPointCount,0);rgn.GetRgnBox(&rect);doublex=rect.left+rect.Width()/2;//计算旋转中心doubley=rect.top+rect.Height()/2;doubledx,dy;for(inti=0;i>m_nType;ar>>m_nPointCount;for(inti=0;i>m_pointList[i];}}//文档类////////////////////////////////////////////////////#defineCHIP_COUNT7classCMyDoc:publicCDocument{DECLARE_DYNCREATE(CMyDoc)CChipm_chipList[CHIP_COUNT];public:voidReset();virtualvoidDeleteContents();virtualvoidSerialize(CArchive&ar);};IMPLEMENT_DYNCREATE(CMyDoc,CDocument)//初始化拼图块voidCMyDoc::Reset(){POINTpointList[MAX_POINTS];pointList[0].x=DELTA;pointList[0].y=DELTA; 课后答案网www.khdaw.compointList[1].x=DELTA+CHIP_WIDTH;pointList[1].y=DELTA;pointList[2].x=DELTA+CHIP_WIDTH/2;pointList[2].y=DELTA+CHIP_WIDTH/2;m_chipList[0].SetChip(1,pointList,3);pointList[0].x=DELTA;pointList[0].y=DELTA;pointList[1].x=DELTA;pointList[1].y=DELTA+CHIP_WIDTH;pointList[2].x=DELTA+CHIP_WIDTH/2;pointList[2].y=DELTA+CHIP_WIDTH/2;m_chipList[1].SetChip(2,pointList,3);pointList[0].x=DELTA+CHIP_WIDTH;pointList[0].y=DELTA;pointList[1].x=DELTA+CHIP_WIDTH;pointList[1].y=DELTA+CHIP_WIDTH/2;pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;pointList[2].y=DELTA+CHIP_WIDTH/4;m_chipList[2].SetChip(3,pointList,3);pointList[0].x=DELTA+CHIP_WIDTH/2;pointList[0].y=DELTA+CHIP_WIDTH/2;pointList[1].x=DELTA+CHIP_WIDTH/4;pointList[1].y=DELTA+(CHIP_WIDTH*3)/4;pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;pointList[2].y=DELTA+(CHIP_WIDTH*3)/4;m_chipList[3].SetChip(4,pointList,3);pointList[0].x=DELTA+CHIP_WIDTH;pointList[0].y=DELTA+CHIP_WIDTH/2;pointList[1].x=DELTA+CHIP_WIDTH;pointList[1].y=DELTA+CHIP_WIDTH;pointList[2].x=DELTA+CHIP_WIDTH/2;pointList[2].y=DELTA+CHIP_WIDTH;m_chipList[4].SetChip(5,pointList,3);pointList[0].x=DELTA+(CHIP_WIDTH*3)/4;pointList[0].y=DELTA+CHIP_WIDTH/4;pointList[1].x=DELTA+CHIP_WIDTH/2;pointList[1].y=DELTA+CHIP_WIDTH/2;pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;pointList[2].y=DELTA+(CHIP_WIDTH*3)/4; 课后答案网www.khdaw.compointList[3].x=DELTA+CHIP_WIDTH;pointList[3].y=DELTA+CHIP_WIDTH/2;m_chipList[5].SetChip(6,pointList,4);pointList[0].x=DELTA;pointList[0].y=DELTA+CHIP_WIDTH;pointList[1].x=DELTA+CHIP_WIDTH/4;pointList[1].y=DELTA+(CHIP_WIDTH*3)/4;pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;pointList[2].y=DELTA+(CHIP_WIDTH*3)/4;pointLis¨t[3].x=DELTA+CHIP_WIDTH/2;pointList[3].y=DELTA+CHIP_WIDTH;m_chipList[6].SetChip(7,pointList,4);//清理文档:关闭文档、建立新文档和打开文档前调用voidCMyDoc::DeleteContents(){Reset();CDocument::DeleteContents();}//系列化:读写文档时自动调用voidCMyDoc::Serialize(CArchive&ar){for(inti=0;im_chipList[i].DrawChip(pDC);}//消息响应:用户点击鼠标左键时调用voidCMyView::OnLButtonDown(UINTnFlags,CPointpoint){CMyDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);for(inti=CHIP_COUNT-1;i>=0;i--)if(pDoc->m_chipList[i].PtInChip(point)){SetCapture();m_bCaptured=TRUE;m_pointMouse=point;m_nCurrIndex=i;break;}}//释放鼠标左键voidCMyView::OnLButtonUp(UINTnFlags,CPointpoint){if(m_bCaptured){ 课后答案网www.khdaw.com::ReleaseCapture();m_bCaptured=FALSE;}}//移动鼠标左键voidCMyView::OnMouseMove(UINTnFlags,CPointpoint){if(m_bCaptured){CMyDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);InvalidateRect(pDoc->m_chipList[m_nCurrIndex].GetRect());CSizeoffset(point-m_pointMouse);pDoc->m_chipList[m_nCurrIndex].MoveTo(offset);InvalidateRect(pDoc->m_chipList[m_nCurrIndex].GetRect());m_pointMouse=point;pDoc->SetModifiedFlag();}}//按下鼠标右键:旋转拼图块voidCMyView::OnRButtonDown(UINTnFlags,CPointpoint){CMyDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);for(inti=CHIP_COUNT-1;i>=0;i--)if(pDoc->m_chipList[i].PtInChip(point)){InvalidateRect(pDoc->m_chipList[i].GetRect());pDoc->m_chipList[i].Rotation();InvalidateRect(pDoc->m_chipList[i].GetRect(),FALSE);pDoc->SetModifiedFlag();break;}}//准备打印:设置打印参数BOOLCMyView::OnPreparePrinting(CPrintInfo*pInfo){pInfo->SetMaxPage(1);returnDoPreparePrinting(pInfo);}//主框架类//////////////////////////////////////////////////classCMainFrame:publicCFrameWnd{ 课后答案网www.khdaw.comDECLARE_DYNCREATE(CMainFrame)};IMPLEMENT_DYNCREATE(CMainFrame,CFrameWnd)//应用程序类///////////////////////////////////////////////#defineIDR_MAINFRAME128//主框架的资源代号classCMyApp:publicCWinApp{public:virtualBOOLInitInstance();DECLARE_MESSAGE_MAP()};BEGIN_MESSAGE_MAP(CMyApp,CWinApp)ON_COMMAND(ID_FILE_NEW,CWinApp::OnFileNew)ON_COMMAND(ID_FILE_OPEN,CWinApp::OnFileOpen)ON_COMMAND(ID_FILE_PRINT_SETUP,CWinApp::OnFilePrintSetup)END_MESSAGE_MAP()//初始化程序实例:建立并登记文档模板BOOLCMyApp::InitInstance(){CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CMyDoc),RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CMyView));AddDocTemplate(pDocTemplate);CCommandLineInfocmdInfo;ParseCommandLine(cmdInfo);if(!ProcessShellCommand(cmdInfo))returnFALSE;m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);returnTRUE;}//全局应用程序对象CMyApptheApp;7-23为例9-3的吹泡泡程序添加一标识符为IDI_MAINICON的图标(该图标应已按11.8:“向项目中添加资源”中的方法建立并加入项目)。说明:建立项目的方法见9.8:“用VisualC++集成开发环境开发Win32应用程序”。程序: 课后答案网www.khdaw.com在例9-3程序前面添加一文件包含命令:#include”resource.h”并将CMyApp::InitInstance()函数修改为:BOOLCMyApp::InitInstance(){HICONhIcon;hIcon=LoadIcon(IDI_MAINICON);//载入图标CMyWnd*pFrame=newCMyWnd;pFrame->Create(0,_T("吹泡泡程序"));pFrame->SetIcon(hIcon,TRUE);//设置大图标pFrame->SetIcon(hIcon,FALSE);//设置小图标pFrame->ShowWindow(m_nCmdShow);this->m_pMainWnd=pFrame;returnTRUE;}7-24显示一张位图文件(.BMP)。说明:首先建立Win32Application空白项目和源代码文件(不要忘记设置项目使之可以使用MFC类库),然后按11.8:“向项目中添加资源”的方法为项目建立资源文件,并将待显示的位图文件作为资源装入项目。程序://Example11-2:显示BMP图片#include#include"resource.h"//框架窗口类classCMyWnd:publicCFrameWnd{CBitmapm_Bitmap;intm_nHeight;intm_nWidth;public:CMyWnd();protected:afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_PAINT()END_MESSAGE_MAP()//框架窗口类的成员函数 课后答案网www.khdaw.comCMyWnd::CMyWnd(){m_Bitmap.LoadBitmap(IDB_BITMAP1);BITMAPBM;m_Bitmap.GetBitmap(&BM);m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;}//响应绘制窗口客户区消息voidCMyWnd::OnPaint(){CPaintDCdc(this);CDCMemDC;MemDC.CreateCompatibleDC(NULL);MemDC.SelectObject(&m_Bitmap);dc.BitBlt(0,0,m_nWidth,m_nHeight,&MemDC,0,0,SRCCOPY);}//应用程序类classCMinMFCApp:publicCWinApp{public:BOOLInitInstance();};//应用程序类的成员函数//初始化应用程序实例BOOLCMinMFCApp::InitInstance(){CMyWnd*pFrame=newCMyWnd;pFrame->Create(0,_T("BeautifulCats”));pFrame->ShowWindow(m_nCmdShow);this->m_pMainWnd=pFrame;returnTRUE;}//全局应用程序对象CMinMFCAppThisApp;7-25修改11-2,使之可以不同比例放大或缩小图象。说明:使用StretchBlt()函数代替BitBlt()函数就可实现图象的缩放显示。在项目中加入一个弹出式菜单(将标识符改为IDR_MAINMENU),内含3个菜单选项:缩小1倍显示,按原尺寸显示和放大1倍显示,其标识符分别改为ID_SHRINK,ID_BESTFIT和ID_ZOOMOUT。 课后答案网www.khdaw.com程序://Example11-3:以不同尺寸显示BMP图片#include#include"resource.h"//框架窗口类classCMyWnd:publicCFrameWnd{CBitmapm_Bitmap;floatm_fTimes;intm_nHeight;intm_nWidth;public:CMyWnd();BOOLPreCreateWindow(CREATESTRUCT&cs);protected:afx_msgvoidOnPaint();afx_msgvoidOnShrink();afx_msgvoidOnBestFit();afx_msgvoidOnZoomOut();DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_PAINT()ON_COMMAND(ID_SHRINK,OnShrink)ON_COMMAND(ID_BESTFIT,OnBestFit)ON_COMMAND(ID_ZOOMOUT,OnZoomOut)END_MESSAGE_MAP()//主窗口类的成员函数CMyWnd::CMyWnd(){BITMAPBM;m_Bitmap.LoadBitmap(IDB_BITMAP1);m_Bitmap.GetBitmap(&BM);m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;m_fTimes=1.0;}//装入菜单BOOLCMyWnd::PreCreateWindow(CREATESTRUCT&cs){cs.hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_MAINMENU));returnCFrameWnd::PreCreateWindow(cs); 课后答案网www.khdaw.com}//缩小图象voidCMyWnd::OnShrink(){m_fTimes=0.5;Invalidate();}//放大图象voidCMyWnd::OnZoomOut(){m_fTimes=2.0;Invalidate();}//原样显示voidCMyWnd::OnBestFit(){m_fTimes=1.0;Invalidate();}//响应绘制窗口客户区消息voidCMyWnd::OnPaint(){CPaintDCdc(this);CDCMemDC;MemDC.CreateCompatibleDC(NULL);MemDC.SelectObject(&m_Bitmap);dc.StretchBlt(0,0,(int)(m_nWidth*m_fTimes),(int)(m_nHeight*m_fTimes),&MemDC,0,0,m_nWidth,m_nHeight,SRCCOPY);}//应用程序类classCMyApp:publicCWinApp{public:BOOLInitInstance();};//应用窗口类的成员函数//初始化应用程序实例BOOLCMyApp::InitInstance(){CMyWnd*pFrame=newCMyWnd;pFrame->Create(0,_T("ShowBitmap1.0"));pFrame->ShowWindow(SW_SHOWMAXIMIZED);pFrame->UpdateWindow(); 课后答案网www.khdaw.comthis->m_pMainWnd=pFrame;returnTRUE;}//全局应用程序对象CMyAppThisApp;7-26拼图程序。设计思想:将一张图片切分成若干小片,打乱顺序任意显示。用户可用鼠标拖动各小片到正确位置以恢复用来的图象。说明:首先创建一Win32Application空项目,然后向项目中添加C++SourceFile(源程序)和ResourceScript(资源描述)文件。在添加资源描述文件后应将其关闭。按本单元介绍的有关内容为本程序添加图标、字符串(窗口标题)和下拉菜单(标题为“游戏”)等资源,其标识符均取IDR_MAINFRAME。为“游戏”下拉菜单添4个菜单选项,一个是“自动拼图”,和一个“结束”,标识符分别为ID_BEGIN和ID_END。剩下3个用来控制拼图的难度,标识符分别为ID_GRAD01,ID_GRAD02和ID_GRAD03。另选一幅漂亮的图片,作为资源装入项目。该图片即拼图的底图。然后输入以下程序,注意在编译前选择使用MFC。程序://Example11-4:拼图程序#include#include#include#include#include"resource.h"#defineMAX_CHIPS500//派生一个框架窗口类classCPuzzleWnd:publicCFrameWnd{CBitmapm_bmpPuzzle;//位图intm_nPuzzleWidth;//位图宽intm_nPuzzleHeight;//位图高intm_nColCount;//每行拼图块数intm_nRowCount;//每列拼图块数CRectm_rectChips[MAX_CHIPS];//每个拼图块的位置intm_nChipWidth;//拼图块宽intm_nChipHeight;//拼图块高BOOLm_bCaptured;CPointm_pointMouse;intm_nCurrIndex; 课后答案网www.khdaw.compublic:CPuzzleWnd();voidInitPuzzle(intcolcount,introwcount);protected:afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnLButtonUp(UINTnFlags,CPointpoint);afx_msgvoidOnMouseMove(UINTnFlags,CPointpoint);afx_msgvoidOnPaint();afx_msgvoidOnShowFig();afx_msgvoidOnGrad01();afx_msgvoidOnGrad02();afx_msgvoidOnGrad03();DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CPuzzleWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_WM_PAINT()ON_COMMAND(ID_SHOWFIG,OnShowFig)ON_COMMAND(ID_GRAD01,OnGrad01)ON_COMMAND(ID_GRAD02,OnGrad02)ON_COMMAND(ID_GRAD03,OnGrad03)END_MESSAGE_MAP()//主窗口类的成员函数//构造函数:装入位图资源CPuzzleWnd::CPuzzleWnd(){BITMAPBM;m_bmpPuzzle.LoadBitmap(IDB_BITMAP1);m_bmpPuzzle.GetObject(sizeof(BM),&BM);m_nPuzzleWidth=BM.bmWidth;m_nPuzzleHeight=BM.bmHeight;InitPuzzle(4,3);m_bCaptured=FALSE;}//初始化拼图数组voidCPuzzleWnd::InitPuzzle(intcolcount,introwcount){m_nColCount=colcount;m_nRowCount=rowcount;m_nChipWidth=m_nPuzzleWidth/m_nColCount;m_nChipHeight=m_nPuzzleHeight/m_nRowCount; 课后答案网www.khdaw.comsrand((unsigned)time(NULL));for(introw=0;row=0;row--)for(intcol=m_nColCount-1;col>=0;col--){intindex=row*m_nColCount+col;if(m_rectChips[index].PtInRect(point)){SetCapture();m_bCaptured=TRUE;m_pointMouse=point;m_nCurrIndex=index;return;}}}//释放鼠标左键voidCPuzzleWnd::OnLButtonUp(UINTnFlags,CPointpoint){if(m_bCaptured){::ReleaseCapture();m_bCaptured=FALSE;}}//移动鼠标左键voidCPuzzleWnd::OnMouseMove(UINTnFlags,CPointpoint){if(m_bCaptured){InvalidateRect(m_rectChips[m_nCurrIndex]);CSizeoffset(point-m_pointMouse);m_rectChips[m_nCurrIndex]+=offset;InvalidateRect(m_rectChips[m_nCurrIndex],FALSE);m_pointMouse=point;}}//显示当前拼图voidCPuzzleWnd::OnPaint(){ 课后答案网www.khdaw.comCPaintDCdc(this);CDCMemDC;MemDC.CreateCompatibleDC(NULL);MemDC.SelectObject(&m_bmpPuzzle);for(introw=0;rowLoadFrame(IDR_MAINMENU);pFrame->ShowWindow(SW_SHOWMAXIMIZED);this->m_pMainWnd=pFrame;returnTRUE;}//全局应用程序对象CPuzzleAppTheApp;//Example11-5:地空战游戏程序#include#include"resource.h"//定义飞机类classCPlane:publicCObject{CPointm_pointPlane;//飞机位置 课后答案网www.khdaw.comCBitmapm_bmpPlane;//飞机图象intm_nWidth;//飞机图象宽intm_nHeight;//飞机图象高public:CPlane();voidShowPlane(CDC*pDC,CDC*pMemDC,CRectClient);CRectGetPlane(){returnCRect(m_pointPlane.x,m_pointPlane.y,m_pointPlane.x+m_nWidth,m_pointPlane.y+m_nHeight);}voidChangePos();voidResetPos(){m_pointPlane.x=0;}};//飞机类的成员函数//构造函数CPlane::CPlane(){m_pointPlane=CPoint(0,50);m_bmpPlane.LoadBitmap(IDB_PLANE);BITMAPBM;m_bmpPlane.GetBitmap(&BM);m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;}//显示飞机voidCPlane::ShowPlane(CDC*pDC,CDC*pMemDC,CRectClient){pMemDC->SelectObject(&m_bmpPlane);pDC->BitBlt(m_pointPlane.x,m_pointPlane.y,m_nWidth,m_nHeight,pMemDC,0,0,SRCAND);}//改变飞机位置voidCPlane::ChangePos(){if(m_pointPlane.x>788)m_pointPlane.x=0;elsem_pointPlane.x+=10;}//定义炸弹类classCBomb:publicCObject{CPointm_pointBomb;//炸弹位置CBitmapm_bmpBomb;//炸弹图象intm_nWidth;//炸弹图象高 课后答案网www.khdaw.comintm_nHeight;//炸弹图象宽public:CBomb();voidShowBomb(CDC*pDC,CDC*pMemDC,CRectClient);CRectGetBomb(){returnCRect(m_pointBomb.x,m_pointBomb.y,m_pointBomb.x+m_nWidth,m_pointBomb.y+m_nHeight);}voidChangePos(intx);voidResetPos(){m_pointBomb.x=0,m_pointBomb.y=80;}};//炸弹类成员函数//炸弹类构造函数CBomb::CBomb(){m_pointBomb.x=0;m_pointBomb.y=80;m_bmpBomb.LoadBitmap(IDB_BOMB);BITMAPBM;m_bmpBomb.GetBitmap(&BM);m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;}//显示炸弹voidCBomb::ShowBomb(CDC*pDC,CDC*pMemDC,CRectClient){pMemDC->SelectObject(&m_bmpBomb);pDC->BitBlt(m_pointBomb.x,m_pointBomb.y,m_nWidth,m_nHeight,pMemDC,0,0,SRCAND);}//改变位置voidCBomb::ChangePos(intx){m_pointBomb.y+=20;if(m_pointBomb.y>480)m_pointBomb.y=80;m_pointBomb.x=x;}//定义高炮类classCTank:publicCObject{CPointm_pointTank;//高炮位置CBitmapm_bmpTank;//高炮图象intm_nWidth;//高炮图象宽intm_nHeight;//高炮图象高 课后答案网www.khdaw.compublic:CTank();voidShowTank(CDC*pDC,CDC*pMemDC,CRectClient);CRectGetTank(){returnCRect(m_pointTank.x,m_pointTank.y,m_pointTank.x+m_nWidth,m_pointTank.y+m_nHeight);}voidChangePos(inttag);voidResetPos(){m_pointTank.x=350;}};//高炮类成员函数//高炮类构造函数CTank::CTank(){m_pointTank.x=350;m_pointTank.y=450;m_bmpTank.LoadBitmap(IDB_TANK);BITMAPBM;m_bmpTank.GetBitmap(&BM);m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;}//显示高炮voidCTank::ShowTank(CDC*pDC,CDC*pMemDC,CRectClient){pMemDC->SelectObject(&m_bmpTank);pDC->BitBlt(m_pointTank.x,m_pointTank.y,m_nWidth,m_nHeight,pMemDC,0,0,SRCAND);}//改变位置voidCTank::ChangePos(inttag){if(tag==0&&m_pointTank.x>0)m_pointTank.x-=20;elseif(tag==1&&m_pointTank.x+m_nWidth<798)m_pointTank.x+=20;}//定义炮弹类classCStone:publicCObject{CPointm_pointStone;//炮弹位置CBitmapm_bmpStone;//炮弹图象intm_nWidth;//炮弹图象宽intm_nHeight;//炮弹图象高BOOLm_bShot;//是否已发射 课后答案网www.khdaw.compublic:CStone();BOOLHaveStone(){return!m_bShot;}voidShot(intx);voidShowStone(CDC*pDC,CDC*pMemDC,CRectClient);CRectGetStone(){returnCRect(m_pointStone.x,m_pointStone.y,m_pointStone.x+m_nWidth,m_pointStone.y+m_nHeight);}voidChangePos();voidResetPos(){m_bShot=FALSE;}voidRefill(){m_bShot=FALSE;}};//炮弹类成员函数//炮弹类构造函数CStone::CStone(){m_bShot=FALSE;m_bmpStone.LoadBitmap(IDB_STONE);BITMAPBM;m_bmpStone.GetBitmap(&BM);m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;}//发射voidCStone::Shot(intx){m_bShot=TRUE;m_pointStone.x=x+48;m_pointStone.y=440;}//显示炮弹voidCStone::ShowStone(CDC*pDC,CDC*pMemDC,CRectClient){if(m_bShot){pMemDC->SelectObject(&m_bmpStone);pDC->BitBlt(m_pointStone.x,m_pointStone.y,m_nWidth,m_nHeight,pMemDC,0,0,SRCAND);}}//改变位置voidCStone::ChangePos(){if(m_bShot)m_pointStone.y-=20; 课后答案网www.khdaw.com}//自定义消息#defineON_WM_GAMEOVER0x0402#defineI_SHOT_YOU0#defineYOU_SHOT_ME1//定义框架窗口类classCMyWnd:publicCFrameWnd{CPlanem_Plane;CBombm_Bomb;CTankm_Tank;CStonem_Stone;CPointm_pointMoutain[5];public:CMyWnd();voidDrawFields(CDC*pDC,CRectClient);BOOLShotOn(CRect&body1,CRect&body2);protected:afx_msgvoidOnPaint();afx_msgvoidOnBegin();afx_msgvoidOnEnd();afx_msgvoidOnTimer(UINTnIDEvent);afx_msgvoidOnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags);afx_msgvoidOnGameOver(UINTtag);DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_PAINT()ON_COMMAND(ID_BEGIN,OnBegin)ON_COMMAND(ID_END,OnEnd)ON_WM_TIMER()ON_WM_KEYDOWN()ON_MESSAGE(ON_WM_GAMEOVER,OnGameOver)END_MESSAGE_MAP()//框架窗口类的成员函数//构造函数CMyWnd::CMyWnd(){m_pointMoutain[0]=CPoint(300,400);m_pointMoutain[1]=CPoint(400,300);m_pointMoutain[2]=CPoint(500,350); 课后答案网www.khdaw.comm_pointMoutain[3]=CPoint(600,250);m_pointMoutain[4]=CPoint(800,400);}//更新窗口客户区voidCMyWnd::OnPaint(){CPaintDCdc(this);CDCMemDC;MemDC.CreateCompatibleDC(NULL);CRectrect;GetClientRect(&rect);DrawFields(&dc,rect);//画战场m_Plane.ShowPlane(&dc,&MemDC,rect);//画对方飞机m_Bomb.ShowBomb(&dc,&MemDC,rect);//画炸弹m_Tank.ShowTank(&dc,&MemDC,rect);//画己方防空导弹车m_Stone.ShowStone(&dc,&MemDC,rect);//画导弹}//响应菜单消息:开始游戏voidCMyWnd::OnBegin(){m_Bomb.ResetPos();m_Plane.ResetPos();m_Tank.ResetPos();m_Stone.ResetPos();Invalidate();SetTimer(1,100,NULL);}//响应菜单消息:游戏结束voidCMyWnd::OnEnd(){KillTimer(1);PostMessage(WM_QUIT);}//定时器消息响应函数voidCMyWnd::OnTimer(UINTnIDEvent){InvalidateRect(m_Plane.GetPlane());//修改飞机位置m_Plane.ChangePos();InvalidateRect(m_Plane.GetPlane(),FALSE);InvalidateRect(m_Bomb.GetBomb());//修改炸弹位置m_Bomb.ChangePos(m_Plane.GetPlane().left);InvalidateRect(m_Bomb.GetBomb(),FALSE);if(!m_Stone.HaveStone())//修改炮弹位置{ 课后答案网www.khdaw.comCRectrect=m_Stone.GetStone();if(rect.top<3)m_Stone.Refill();else{InvalidateRect(rect);m_Stone.ChangePos();}InvalidateRect(m_Stone.GetStone(),FALSE);}//判断射击效果if(!m_Stone.HaveStone()&&ShotOn(m_Plane.GetPlane(),m_Stone.GetStone()))SendMessage(ON_WM_GAMEOVER,YOU_SHOT_ME);elseif(ShotOn(m_Tank.GetTank(),m_Bomb.GetBomb()))SendMessage(ON_WM_GAMEOVER,I_SHOT_YOU);}//自定义的游戏结束消息响应函数voidCMyWnd::OnGameOver(UINTtag){KillTimer(1);if(tag==I_SHOT_YOU)MessageBox("我砸到你了!!!");elseMessageBox("你击中我了!!!");}//按键消息响应函数voidCMyWnd::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags){if(nChar==VK_LEFT)//使用<键左移高炮{InvalidateRect(m_Tank.GetTank());m_Tank.ChangePos(0);InvalidateRect(m_Tank.GetTank(),FALSE);}elseif(nChar==VK_RIGHT)//使用>键右移高炮{InvalidateRect(m_Tank.GetTank());m_Tank.ChangePos(1);InvalidateRect(m_Tank.GetTank());}elseif(nChar==32&&m_Stone.HaveStone())//使用空格键发炮m_Stone.Shot(m_Tank.GetTank().left);}//画战场 课后答案网www.khdaw.comvoidCMyWnd::DrawFields(CDC*pDC,CRectClient){CBrush*pOldBrush,brushSky,brushGrass,brushMoutain;CRectrect(Client);brushSky.CreateSolidBrush(RGB(127,200,255));//画天空pOldBrush=pDC->SelectObject(&brushSky);pDC->Rectangle(rect);pDC->SelectObject(pOldBrush);brushGrass.CreateSolidBrush(RGB(0,255,0));//画草地pOldBrush=pDC->SelectObject(&brushGrass);rect.top=400;pDC->Rectangle(rect);pDC->SelectObject(pOldBrush);brushMoutain.CreateSolidBrush(RGB(125,50,0));//画大山pOldBrush=pDC->SelectObject(&brushMoutain);pDC->Polygon(m_pointMoutain,5);pDC->SelectObject(pOldBrush);}//判断射击效果BOOLCMyWnd::ShotOn(CRect&body1,CRect&body2){returnbody1.PtInRect(body2.TopLeft());}//定义应用程序类classCMyApp:publicCWinApp{public:BOOLInitInstance();};//初始化实例函数BOOLCMyApp::InitInstance(){CMyWnd*pFrame=newCMyWnd;pFrame->LoadFrame(IDR_MAINFRAME);pFrame->ShowWindow(SW_SHOWMAXIMIZED);this->m_pMainWnd=pFrame;returnTRUE;}//说明应用程序类的全局对象CMyAppThisApp; 课后答案网www.khdaw.com第八章多态性8-1什么叫做多态性?在C++中是如何实现多态的?解:多态是指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象。C++支持的多态有多种类型,重载(包括函数重载和运算符重载)和虚函数是其中主要的方式。8-2什么叫做抽象类?抽象类有何作用?抽象类的派生类是否一定要给出纯虚函数的实现?解:带有纯虚函数的类是抽象类。抽象类的主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特性。抽象类声明了一组派生类共同操作接口的通用语义,而接口的完整实现,即纯虚函数的函数体,要由派生类自己给出。但抽象类的派生类并非一定要给出纯虚函数的实现,如果派生类没有给出纯虚函数的实现,这个派生类仍然是一个抽象类。8-3声明一个参数为整型,无返回值,名为fn1的虚函数。解:virtualvoidfn1(int);8-4在C++中,能否声明虚构造函数?为什么?能否声明虚析构函数?有何用途?解:在C++中,不能声明虚构造函数,多态是不同的对象对同一消息有不同的行为特性,虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此虚构造函数是没有意义的;可以声明虚析构函数,析构函数的功能是在该类对象消亡之前进行一些必要的清理工作,如果一个类的析构函数是虚函数,那么,由它派生而来的所有子类的析构函数也是虚函数。析构函数设置为虚函数之后,在使用指针引用时可以动态联编,实现运行时的多态,保证使用基类的指针就能够调用适当的析构函数针对不同的对象进行清理工作。 课后答案网www.khdaw.com8-5实现重载函数Double(x),返回值为输入参数的两倍;参数分别为整型、长整型、浮点型、双精度型,返回值类型与参数一样。解:源程序:#includeintDouble(int);longDouble(long);floatDouble(float);doubleDouble(double);intmain(){intmyInt=6500;longmyLong=65000;floatmyFloat=6.5F;doublemyDouble=6.5e20;intdoubledInt;longdoubledLong;floatdoubledFloat;doubledoubledDouble;cout<<"myInt:"<classRectangle{public:Rectangle();Rectangle(intwidth,intlength);~Rectangle(){}intGetWidth()const{returnitsWidth;}intGetLength()const{returnitsLength;}private:intitsWidth;intitsLength;};Rectangle::Rectangle(){itsWidth=5;itsLength=10;}Rectangle::Rectangle(intwidth,intlength){itsWidth=width;itsLength=length;}intmain(){RectangleRect1;cout<<"Rect1width:"<>aWidth;cout<<"nEnteralength:";cin>>aLength;RectangleRect2(aWidth,aLength);cout<<"nRect2width:"<classCounter{public:Counter();Counter(USHORTinitialValue);~Counter(){}USHORTGetItsVal()const{returnitsVal;}voidSetItsVal(USHORTx){itsVal=x;}Counteroperator+(constCounter&);private:USHORTitsVal;};Counter::Counter(USHORTinitialValue):itsVal(initialValue){}Counter::Counter():itsVal(0){} 课后答案网www.khdaw.comCounterCounter::operator+(constCounter&rhs){returnCounter(itsVal+rhs.GetItsVal());}intmain(){CountervarOne(2),varTwo(4),varThree;varThree=varOne+varTwo;cout<<"varOne:"<classMammal{public:Mammal():itsAge(1){cout<<"Mammalconstructor...n";}~Mammal(){cout<<"Mammaldestructor...n";}virtualvoidSpeak()const{cout<<"Mammalspeak!n";}};classDog:publicMammal{public:Dog(){cout<<"DogConstructor...n";}~Dog(){cout<<"Dogdestructor...n";}voidSpeak()const{cout<<"Woof!n";}}; 课后答案网www.khdaw.comintmain(){Mammal*pDog=newDog;pDog->Speak();return0;}程序运行输出:Mammalconstructor...Dogconstructor...Woof!Dogdestructor...Mammaldestructor...8-9定义一个Shape抽象类,在此基础上派生出Rectangle和Circle,二者都有GetArea()函数计算对象的面积,GetPerim()函数计算对象的周长。解:源程序:#includeclassShape{public:Shape(){}~Shape(){}virtualfloatGetArea()=0;virtualfloatGetPerim()=0;};classCircle:publicShape{public:Circle(floatradius):itsRadius(radius){}~Circle(){}floatGetArea(){return3.14*itsRadius*itsRadius;}floatGetPerim(){return6.28*itsRadius;}private:floatitsRadius;}; 课后答案网www.khdaw.comclassRectangle:publicShape{public:Rectangle(floatlen,floatwidth):itsLength(len),itsWidth(width){};~Rectangle(){};virtualfloatGetArea(){returnitsLength*itsWidth;}floatGetPerim(){return2*itsLength+2*itsWidth;}virtualfloatGetLength(){returnitsLength;}virtualfloatGetWidth(){returnitsWidth;}private:floatitsWidth;floatitsLength;};voidmain(){Shape*sp;sp=newCircle(5);cout<<"TheareaoftheCircleis"<GetArea()<GetPerim()<GetArea()<GetPerim()<classPoint{ 课后答案网www.khdaw.compublic:Point&operator++();Pointoperator++(int);Point&operator--();Pointoperator--(int);Point(){_x=_y=0;}intx(){return_x;}inty(){return_y;}private:int_x,_y;};Point&Point::operator++(){_x++;_y++;return*this;}PointPoint::operator++(int){Pointtemp=*this;++*this;returntemp;}Point&Point::operator--(){_x--;_y--;return*this;}PointPoint::operator--(int){Pointtemp=*this;--*this;returntemp;} 课后答案网www.khdaw.comvoidmain(){PointA;cout<<"A的值为:"<classBaseClass{public:virtualvoidfn1();voidfn2();};voidBaseClass::fn1(){cout<<"调用基类的虚函数fn1()"<fn1();pBaseClass->fn2();pDerivedClass->fn1();pDerivedClass->fn2();}程序运行输出:调用派生类的函数fn1()调用基类的非虚函数fn2()调用派生类的函数fn1()调用派生类的函数fn2()8-12定义一个基类BaseClass,从它派生出类DerivedClass,BaseClass中定义虚析构函数,在主程序中将一个DerivedClass的对象地址赋给一个BaseClass的指针,观察运行过程。解:#include 课后答案网www.khdaw.comclassBaseClass{public:virtual~BaseClass(){cout<<"~BaseClass()"<classPoint{public:Point(){X=Y=0;}Point(unsignedx,unsignedy){X=x;Y=y;}unsignedx(){returnX;}unsignedy(){returnY;}voidPrint(){cout<<"Point("<InsertString(-1,"办公室");pLB->InsertString(-1,"开发部");pLB->InsertString(-1,"生产部");pLB->InsertString(-1,"销售部");pLB->InsertString(-1,"人事部");returnCDialog::OnInitDialog();}其中GetDlgItem()为对话框类的成员函数,用于取对话框控件的指针。为项目添加有关自定义的职工类CEmployee。选择DeveloperStudio菜单的Insert/NewClass…选项,调出NewClass对话框。在ClassType组合框中选择Generic(普通类),填写类名CEmployee,在对话框下方的Baseclass(es)框中输入基类CObject。在Workspace窗口的ClassView中选择生成的CEmployee类的定义,添加代码:classCEmployee:publicCObject{DECLARE_SERIAL(CEmployee)public:CStringm_strName;//姓名intm_nSex;//性别COleDateTimem_tBirthdate;//出生日期BOOLm_bMarried;//婚否CStringm_strDept;//工作部门CStringm_strPosition;//职务floatm_fSalary;//工资CEmployee(){}CEmployee&operator=(CEmployee&e);virtual~CEmployee();virtualvoidSerialize(CArchive&ar);};CEmployee类的对象即为一个职工的档案,我们用序列化实现文档的存取,所以要为CEmployee类编写序列化代码。这包括DECLARE_SERIAL()宏和IMPLEMENT_SERIAL()宏(在CEmployee类的源代码文件中),一个没有参数的构造函数,重载的赋值运算符和Serialize()成员函数。在CEmployee类的源代码文件中添加以下代码:IMPLEMENT_SERIAL(CEmployee,CObject,1) 课后答案网www.khdaw.com//重载的赋值运算符CEmployee&CEmployee::operator=(CEmployee&e){m_strName=e.m_strName;m_nSex=e.m_nSex;m_tBirthdate=e.m_tBirthdate;m_bMarried=e.m_bMarried;m_strDept=e.m_strDept;m_strPosition=e.m_strPosition;m_fSalary=e.m_fSalary;return*this;}//序列化函数voidCEmployee::Serialize(CArchive&ar){CObject::Serialize(ar);if(ar.IsStoring()){ar<>m_strName;ar>>m_nSex;ar>>m_tBirthdate;ar>>m_bMarried;ar>>m_strDept;ar>>m_strPosition;ar>>m_fSalary;}}然后修改文档类CMyDocument类定义,添加一个CEmployee类的数组:#include"employee.h"#defineMAX_EMPLOYEE1000classCMy1501Doc:publicCDocument{DECLARE_DYNCREATE(CMy1501Doc)public: 课后答案网www.khdaw.comCEmployeem_empList[MAX_EMPLOYEE];intm_nCount;public:virtualBOOLOnNewDocument();virtualvoidSerialize(CArchive&ar);virtualvoidDeleteContents();DECLARE_MESSAGE_MAP()};为了节省篇幅,这段程序经过删节,与原来由AppWizard生成的程序有所不同。其中黑体部分为要添加的代码。注意重载成员函数DeleteContents()可以手工进行,也可以通过ClassWizard进行。Serialize()和DeleteContents()两个成员函数的代码如下:voidCMy1501Doc::Serialize(CArchive&ar){if(ar.IsStoring())ar<>m_nCount;for(inti=0;im_nCount);pDC->SetTextColor(RGB(255,0,0));pDC->TextOut(40,40,s);s.Format("职工编号:%d",m_nCurrEmp+1);pDC->TextOut(340,40,s);pDC->MoveTo(40,70);pDC->LineTo(600,70);//如果档案非空,显示当前记录if(pDoc->m_nCount>0){//显示栏目名称pDC->SetTextColor(RGB(0,0,0));pDC->TextOut(140,90,"姓名:");pDC->TextOut(140,130,"性别:");pDC->TextOut(140,170,"出生日期:");pDC->TextOut(140,210,"婚姻状态:");pDC->TextOut(140,250,"部门:");pDC->TextOut(140,290,"职务:");pDC->TextOut(140,330,"工资:");//显示栏目内容pDC->SetTextColor(RGB(0,0,255));pDC->TextOut(300,90,pDoc->m_empList[m_nCurrEmp].m_strName);if(pDoc->m_empList[m_nCurrEmp].m_nSex==0)pDC->TextOut(300,130,"男");elsepDC->TextOut(300,130,"女");s=pDoc->m_empList[m_nCurrEmp].m_tBirthdate.Format("%Y.%m.%d");pDC->TextOut(300,170,s);if(pDoc->m_empList[m_nCurrEmp].m_bMarried)pDC->TextOut(300,210,"已婚");elsepDC->TextOut(300,210,"未婚");pDC->TextOut(300,250,pDoc->m_empList[m_nCurrEmp].m_strDept);pDC->TextOut(300,290,pDoc->m_empList[m_nCurrEmp].m_strPosition);s.Format("%8.2f",pDoc->m_empList[m_nCurrEmp].m_fSalary);pDC->TextOut(300,330,s);}}在编辑资源时,我们框架窗口添加了5个菜单选项,并将对应的消息响应函数映射到了视图类中。这些消息响应函数的代码如下:voidCMy1501View::OnAppend(){CMy1501Doc*pDoc=GetDocument();ASSERT_VALID(pDoc); 课后答案网www.khdaw.comCEmpDlgdlg;if(dlg.DoModal()==IDOK){pDoc->m_nCount++;m_nCurrEmp=pDoc->m_nCount-1;pDoc->m_empList[m_nCurrEmp].m_strName=dlg.m_strName;pDoc->m_empList[m_nCurrEmp].m_nSex=dlg.m_nSex;pDoc->m_empList[m_nCurrEmp].m_tBirthdate=dlg.m_tBirthdate;pDoc->m_empList[m_nCurrEmp].m_bMarried=dlg.m_bMarried;pDoc->m_empList[m_nCurrEmp].m_strDept=dlg.m_strDept;pDoc->m_empList[m_nCurrEmp].m_strPosition=dlg.m_strPosition;pDoc->m_empList[m_nCurrEmp].m_fSalary=dlg.m_fSalary;pDoc->SetModifiedFlag();Invalidate();}}//删除当前记录voidCMy1501View::OnDelete(){CMy1501Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);if(pDoc->m_nCount){for(inti=m_nCurrEmp;im_nCount-1;i++)pDoc->m_empList[i]=pDoc->m_empList[i+1];pDoc->m_nCount--;if(m_nCurrEmp>pDoc->m_nCount-1)m_nCurrEmp=pDoc->m_nCount-1;pDoc->SetModifiedFlag();Invalidate();}}//编辑当前记录voidCMy1501View::OnEdit(){CMy1501Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);if(pDoc->m_nCount){CEmpDlgdlg;dlg.m_strName=pDoc->m_empList[m_nCurrEmp].m_strName;dlg.m_nSex=pDoc->m_empList[m_nCurrEmp].m_nSex;dlg.m_tBirthdate=pDoc->m_empList[m_nCurrEmp].m_tBirthdate;dlg.m_bMarried=pDoc->m_empList[m_nCurrEmp].m_bMarried; 课后答案网www.khdaw.comdlg.m_strDept=pDoc->m_empList[m_nCurrEmp].m_strDept;dlg.m_strPosition=pDoc->m_empList[m_nCurrEmp].m_strPosition;dlg.m_fSalary=pDoc->m_empList[m_nCurrEmp].m_fSalary;if(dlg.DoModal()==IDOK){pDoc->m_empList[m_nCurrEmp].m_strName=dlg.m_strName;pDoc->m_empList[m_nCurrEmp].m_nSex=dlg.m_nSex;pDoc->m_empList[m_nCurrEmp].m_tBirthdate=dlg.m_tBirthdate;pDoc->m_empList[m_nCurrEmp].m_bMarried=dlg.m_bMarried;pDoc->m_empList[m_nCurrEmp].m_strDept=dlg.m_strDept;pDoc->m_empList[m_nCurrEmp].m_strPosition=dlg.m_strPosition;pDoc->m_empList[m_nCurrEmp].m_fSalary=dlg.m_fSalary;pDoc->SetModifiedFlag();Invalidate();}}}//查看后一记录voidCMy1501View::OnNext(){CMy1501Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);if(pDoc->m_nCount>1){if(m_nCurrEmp==pDoc->m_nCount-1)m_nCurrEmp=0;elsem_nCurrEmp++;}Invalidate();}//查看前一记录voidCMy1501View::OnPrev(){CMy1501Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);if(pDoc->m_nCount>1){if(m_nCurrEmp==0)m_nCurrEmp=pDoc->m_nCount-1;elsem_nCurrEmp--;}Invalidate(); 课后答案网www.khdaw.com}8-15用基于对话框的应用程序结构实现例14-5的彩色吹泡泡程序。由于对话框本身结构简单,没有明显的客户区,颜色也不醒目,所以我们在对话框上自行建立一个矩形区域作为吹泡泡的客户区,并通过一个“颜色设置”按钮来设置泡泡的颜色。说明:用AppWizard建立一个基于对话框的应用程序框架(参看15.4:“用AppWizard生成基于对话框的应用程序”),所有设置均使用缺省值。使用对话框模板编辑器编辑作为主界面窗口的对话框模板,将其上的静态文本控件和“Cancel”按钮删除,将“OK”按钮的Caption设置为“完成”,并将对话框大小调整为400×300左右。为对话框模板添加一个Picture控件,将其Type设置为Frame,Color设置为Black,并设置Sunken属性(在Styles选项卡中)。调整其位置为(7,7),大小为287×287。这个框中即为自定义的吹泡泡客户区,所有的吹泡泡活动均在该区域中进行。为对话框模板添加一个按钮,将其ID改为IDC_COLOR,Caption改为“颜色设置”。使用ClassWizard为对话框类添加一个鼠标左键消息响应函数OnLButtonDown()和一个按钮命令消息响应函数OnColor()。程序:在对话框类的头文件前面添加一行:#defineMAX_BUBBLE250并在对话框类定义中添加存放泡泡的几何参数和颜色的数组数据成员:CRectm_rectBubble[MAX_BUBBLE];COLORREFm_colorBubble[MAX_BUBBLE];intm_nBubbleCount;以及一个存放自定义客户区矩形的数据成员和一个存放当前泡泡颜色设置的数据成员:CRectm_rectClient;COLORREFm_colorCurrent;修改对话框类的OnInitDialog()成员函数,添加计算自定义客户区位置和大小的代码,并将泡泡的数目初始化为0:BOOLCMyDlg::OnInitDialog(){CDialog::OnInitDialog();CStatic*pST=(CStatic*)GetDlgItem(IDC_CLIENT);pST->GetWindowRect(&m_rectClient);ScreenToClient(&m_rectClient);m_nBubbleCount=0;returnTRUE;}修改OnPaint()成员函数,添加画出泡泡的有关代码:voidCMyDlg::OnPaint() 课后答案网www.khdaw.com{CPaintDCdc(this);CRgnrgn;rgn.CreateRectRgnIndirect(&m_rectClient);//生成一个区域对象dc.SelectClipRgn(&rgn);//选择区域dc.Rectangle(m_rectClient);//将客户区背景设置CBrushbrushNew,*pbrushOld;//白色for(inti=0;i#include#ifndefNULLconstintNULL=0;#endif//NULL//错误类型集合,共有三种类型的错误:数组大小错误、内存分配错误和下标越界enumErrorType{invalidArraySize,memoryAllocationError,indexOutOfRange};//错误信息char*errorMsg[]={"Invalidarraysize","Memoryallocationerror","Invalidindex:"};//数组类模板templateclassArray{private:T*alist;//T类型指针,用于存放动态分配的数组内存首地址intsize;//数组大小(元素个数)//错误处理函数voidError(ErrorTypeerror,intbadIndex=0)const;public:Array(intsz=50);//构造函数Array(constArray&A);//拷贝构造函数~Array(void);//析构函数//重载"="使数组对象可以整体赋值Array&operator=(constArray&rhs); 课后答案网www.khdaw.com//重载"[]"与T*,使Array对象可以起到C++普通数组的作用T&operator[](inti);operatorT*(void)const;intListSize(void)const;//取数组的大小voidResize(intsz);//修改数组的大小};//以下为类成员函数的实现//模扳函数Error实现输出错误信息的功能templatevoidArray::Error(ErrorTypeerror,intbadIndex)const{cout<Array::Array(intsz){if(sz<=0)//sz为数组大小(元素个数),若小于0,则输出错误信息Error(invalidArraySize);size=sz;//将元素个数赋值给变量sizealist=newT[size];//动态分配size个T类型的元素空间if(alist==NULL)//如果分配内存不成功,输出错误信息Error(memoryAllocationError);}//析构函数templateArray::~Array(void){delete[]alist;} 课后答案网www.khdaw.com//拷贝构造函数templateArray::Array(constArray&X){//从对象X取得数组大小,并赋值给当前对象的成员intn=X.size;size=n;//为对象申请内存并进行出错检查alist=newT[n];//动态分配n个T类型的元素空间if(alist==NULL)//如果分配内存不成功,输出错误信息Error(memoryAllocationError);//从对象X复制数组元素到本对象T*srcptr=X.alist;//X.alist是对象X的数组首地址T*destptr=alist;//alist是本对象中的数组首地址while(n--)//逐个复制数组元素*destptr++=*srcptr++;}//重载"="运算符,将对象rhs赋值给本对象。实现对象之间的整体赋值templateArray&Array::operator=(constArray&rhs){intn=rhs.size;//取rhs的数组大小//如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配if(size!=n){delete[]alist;//删除数组原有内存alist=newT[n];//重新分配n个元素的内存if(alist==NULL)//如果分配内存不成功,输出错误信息Error(memoryAllocationError);size=n;//记录本对象的数组大小}//从rhs向本对象复制元素T*destptr=alist;T*srcptr=rhs.alist;while(n--)*destptr++=*srcptr++;//返回指向本对象的指针return*this; 课后答案网www.khdaw.com}//重载下标操作符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能templateT&Array::operator[](intn){//检查下标是否越界if(n<0||n>size-1)Error(indexOutOfRange,n);//返回下标为n的数组元素returnalist[n];}//重载指针转换操作符,使指向T类对象的指针成为当前对象中私有数组的首地址。//因而可以象使用普通数组首地址一样使用T类型指针templateArray::operatorT*(void)const{//返回当前对象中私有数组的首地址returnalist;}//取当前数组的大小templateintArray::ListSize(void)const{returnsize;}//将数组大小修改为sztemplatevoidArray::Resize(intsz){//检查是否sz<=0if(sz<=0)Error(invalidArraySize);//如果指定的大小与原有大小一样,什么也不做if(sz==size)return;//申请新的数组内存,并测试是否申请成功T*newlist=newT[sz];if(newlist==NULL)Error(memoryAllocationError); 课后答案网www.khdaw.com//将sz与size中较小的一个赋值给nintn=(sz<=size)?sz:size;//将原有数组中前n个元素复制到新数组中T*srcptr=alist;//原数组alist的首地址T*destptr=newlist;//新数组newlist的首地址while(n--)//复制数组元素*destptr++=*srcptr++;//删除原数组delete[]alist;//使alist指向新数组,并更新sizealist=newlist;size=sz;}#endif//ARRAY_CLASS//test9_1.cpp#include#includevoidmain(){intn;doubleAverScore,TotalScore=0;cout<<"请输入学生人数:";cin>>n;ArrayScore(n);for(inti=0;i>Score[i];TotalScore+=Score[i];}AverScore=TotalScore/n;cout<<"平均成绩为"<classDNode{private://circularlinkstotheleftandrightDNode*left;DNode*right;public://dataispublic 课后答案网www.khdaw.comTdata;//constructorsDNode(void);DNode(constT&item);//listmodificationmethodsvoidInsertRight(DNode*p);voidInsertLeft(DNode*p);DNode*DeleteNode(void);//obtainaddressofthenextnodetotheleftorrightDNode*NextNodeRight(void)const;DNode*NextNodeLeft(void)const;};//constructorthatcreatesanemptylistand//leavesthedatauninitialized.useforheadertemplateDNode::DNode(void){//initializethenodesoitpointstoitselfleft=right=this;}//constructorthatcreatesanemptylistandinitializesdatatemplateDNode::DNode(constT&item){//setnodetopointtoitselfandinitializedataleft=right=this;data=item;}//insertanodeptotherightofcurrentnodetemplatevoidDNode::InsertRight(DNode*p){//linkptoitssuccessorontherightp->right=right;right->left=p; 课后答案网www.khdaw.com//linkptothecurrentnodeonitsleftp->left=this;right=p;}//insertanodeptotheleftofcurrentnodetemplatevoidDNode::InsertLeft(DNode*p){//linkptoitssuccessorontheleftp->left=left;left->right=p;//linkptothecurrentnodeonitsrightp->right=this;left=p;}//unlinkthecurrentnodefromthelistandreturnitsaddresstemplateDNode*DNode::DeleteNode(void){//nodetotheleftmustbelinkedtocurrentnode"srightleft->right=right;//nodetotherightmustbelinkedtocurrentnode"sleftright->left=left;//returntheaddressofthecurrentnodereturnthis;}//returnpointertothenextnodeontherighttemplateDNode*DNode::NextNodeRight(void)const{returnright;}//returnpointertothenextnodeonthelefttemplateDNode*DNode::NextNodeLeft(void)const{returnleft; 课后答案网www.khdaw.com}#endif//DOUBLY_LINKED_NODE_CLASS9-5使用本章中的链表类定义两个整型链表A和B,分别插入5个元素,然后把B中的元素加入A的尾部。解:本题的解答见“实验指导”部分“实验九”。9-6从教材第9章的链表类LinkedList中派生有序链表类OrderList,添加成员函数InsertOrder,实现链表元素的有序(递增)插入。定义两个整型有序链表A和B,分别按递增顺序插入5个元素,然后把B中的元素插入A中,保持A中递增顺序不变。解:#include#include"link.h"//参见"实验指导"部分"实验九"templateclassLink:publicLinkedList{public:voidInsertOrder(constT&item);};templatevoidLink::InsertOrder(constT&item){Reset();while(!EndOfList()){if(itemA,B;inti,item;cout<<"请输入加入链表A的五个整数:";for(i=0;i<5;i++){cin>>item;A.InsertOrder(item);}cout<<"请输入加入链表B的五个整数:";for(i=0;i<5;i++){cin>>item;B.InsertOrder(item);}cout<#includeusingnamespacestd;typedefstackSTACK_INT;voidmain(){STACK_INTstack1;cout<<"stack1.empty()returned"<<(stack1.empty()?"true":"false")<、>=、<、<=等运算符,以对两个不同的栈进行算术比较运算操作,请构造一个整型栈,以==、<运算为例,对两个栈进行算术比较运算,体会其比较归者规则;运行程序,观察其输出。解:源程序:#include#includeusingnamespacestd;typedefstackSTACK_DOUBLE;voidmain(){STACK_DOUBLEstack1,stack2;//Additem4.0toStack1.Stack1contains4.0.cout<<"stack1.push(4.0)s1=[4.0]"<#includeusingnamespacestd;typedefqueueINTQUEUE;typedefqueueCHARQUEUE;voidmain(void){intsize_q;INTQUEUEq;CHARQUEUEp;//Insertitemsinthequeue(useslist)q.push(42);q.push(100);q.push(49);q.push(201);//Outputthesizeofqueuesize_q=q.size();cout<<"sizeofqis:"<#includeusingnamespacestd;typedefdequeCHARDEQUE;voidprint_contents(CHARDEQUEdeque,char*);voidmain(){//createawith3A"sCHARDEQUEa(3,"A");//createbwith4B"s.CHARDEQUEb(4,"B");//printoutthecontentsprint_contents(a,"a");print_contents(b,"b");//swapaandba.swap(b);print_contents(a,"a");print_contents(b,"b");//letusswapitbacka.swap(b);print_contents(a,"a");print_contents(b,"b");//assignthecontentsofbtoaa.assign(b.begin(),b.end());print_contents(a,"a");//assignthefirsttwoitemsofbtoaa.assign(b.begin(),b.begin()+2);print_contents(a,"a"); 课后答案网www.khdaw.com//assign3"Z"stoaa.assign(3,"Z");print_contents(a,"a");}//functiontoprintthecontentsofdequevoidprint_contents(CHARDEQUEdeque,char*name){CHARDEQUE::iteratorpdeque;cout<<"Thecontentsof"<#includeusingnamespacestd; 课后答案网www.khdaw.comtypedefdequeCHARDEQUE;voidprint_contents(CHARDEQUEdeque,char*);voidmain(){//createawithA,B,CandDCHARDEQUEa;a.push_back("A");a.push_back("B");a.push_back("C");a.push_back("D");//printoutthecontentsprint_contents(a,"a");cout<<"Thefirstelementofais"<#includeusingnamespacestd;typedefdequeCHARDEQUE;voidprint_contents(CHARDEQUEdeque);voidmain(){//createawith3A"sCHARDEQUEa(3,"A");//createbwith2B"s.CHARDEQUEb(2,"B");//printoutthecontentsprint_contents(a);print_contents(b); 课后答案网www.khdaw.com//insert"X"tothebeginningofaa.insert(a.begin(),"X");print_contents(a);//insert"Y"totheendofaa.insert(a.end(),"Y");print_contents(a);//inset3"Z"stooneitembeforetheendofaa.insert(a.end()-1,3,"Z");print_contents(a);//inserttotheendofafromba.insert(a.end(),b.begin(),b.end());print_contents(a);}//functiontoprintthecontentsofdequevoidprint_contents(CHARDEQUEdeque){CHARDEQUE::iteratorpdeque;cout<<"Theoutputis:";for(pdeque=deque.begin();pdeque!=deque.end();pdeque++){cout<<*pdeque<<"";}cout<#includeusingnamespacestd;typedefdequeCHARDEQUE;voidprint_contents(CHARDEQUEdeque,char*);voidmain(){//createawithA,B,CandDCHARDEQUEa;a.push_back("A");a.push_back("B");a.push_back("C");a.push_back("D");//printoutthecontentsprint_contents(a,"a");cout<<"max_sizeofais"<classTreeNode{private:TreeNode*left;//左指针TreeNode*right;//右指针public:Tdata;//结点数据//构造函数TreeNode(constT&item,TreeNode*lptr=NULL,TreeNode*rptr=NULL);//访问指针域的函数TreeNode*Left(void)const;//取得左指针TreeNode*Right(void)const;//取得右指针//删除当前结点的左右子树voidrelease();};//构造函数,初始化数据域和指针域templateTreeNode::TreeNode(constT&item,TreeNode*lptr,TreeNode*rptr):data(item),left(lptr),right(rptr){}//取得左指针templateTreeNode*TreeNode::Left(void)const{returnleft;}//取得右指针templateTreeNode*TreeNode::Right(void)const{returnright;} 课后答案网www.khdaw.com//删除当前结点的左右子树templatevoidTreeNode::release(){if(left){//删除左子树left->release();deleteleft;left=NULL;}if(right){//删除右子树right->release();deleteright;right=NULL;}}#endif//TREENODE_CLASS//test9_17.cpp#include#include"treenode.h"voidmain(void){TreeNodeD("D"),E("E");TreeNodeB("B",&D,&E),C("C");TreeNodeA("A",&B,&C);}第十章群体数据的组织 课后答案网www.khdaw.com10-1简单说明插入排序的算法思想。解:插入排序的基本思想是:每一步将一个待排序元素按其关键字值的大小插入到已排序序列的适当位置上,直到待排序元素插入完为止。10-2初始化整型数组data1[]={1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20},调用教材中的直接插入排序函数模板进行排序,对此函数模板稍做修改,加入输出语句,在每插入一个待排序元素后显示整个数组,观察排序过程中数据的变化,加深对插入排序算法的理解。解:#includetemplatevoidInsertionSort(TA[],intn){inti,j;Ttemp;//将下标为1~n-1的元素逐个插入到已排序序列中适当的位置for(i=1;i0&&temp=A[j-1]时,j便是应插入的位置。//若达到j==0,则0是应插入的位置。A[j]=A[j-1];//将元素逐个后移,以便找到插入位置时可立即插入。j--;}//插入位置已找到,立即插入。A[j]=temp;//输出数据for(intk=0;k//辅助函数:交换x和y的值templatevoidSwap(T&x,T&y){Ttemp;temp=x;x=y;y=temp;}//用选择法对数组A的n个元素进行排序templatevoidSelectionSort(TA[],intn){intsmallIndex;//每以趟中选出的最小元素之下标inti,j;//sortA[0]..A[n-2],andA[n-1]isinplacefor(i=0;i//辅助函数:交换x和y的值templatevoidSwap(T&x,T&y){Ttemp;temp=x;x=y;y=temp;}//用起泡法对数组A的n个元素进行排序templatevoidBubbleSort(TA[],intn){ 课后答案网www.khdaw.cominti,j;intlastExchangeIndex;//用于记录每趟被交换的最后一对元素中较小的下标i=n-1;//i是下一趟需参与排序交换的元素之最大下标while(i>0)//持续排序过程,直到最后一趟排序没有交换发生,或已达n-1趟{lastExchangeIndex=0;//每一趟开始时,设置交换标志为0(未交换)for(j=0;j//辅助函数:交换x和y的值templatevoidSwap(T&x,T&y){Ttemp;temp=x;x=y;y=temp;}//用起泡法对数组A的n个元素进行排序templatevoidBubbleSort(TA[],intn){ 课后答案网www.khdaw.cominti,j;intlastExchangeIndex;//用于记录每趟被交换的最后一对元素中较小的下标i=n-1;//i是下一趟需参与排序交换的元素之最大下标while(i>0)//持续排序过程,直到最后一趟排序没有交换发生,或已达n-1趟{lastExchangeIndex=0;//每一趟开始时,设置交换标志为0(未交换)for(j=0;jA[j])//如果元素A[j+1] 课后答案网www.khdaw.comtemplateintSeqSearch(Tlist[],intn,Tkey){for(inti=0;i>n;cout<<"数据为:"<//用折半查找方法,在元素呈升序排列的数组list中查找值为key的元素templateintBinSearch(Tlist[],intn,Tkey){intmid,low,high;Tmidvalue;low=0;high=n-1;while(low<=high)//low<=high表示整个数组尚未查找完{mid=(low+high)/2;//求中间元素的下标midvalue=list[mid];//取出中间元素的值if(key==midvalue)returnmid;//若找到,返回下标elseif(key>n;cout<<"数据为:"<voidmain(){ofstreamfile1("test.txt");file1<<"已成功写入文件!";file1.close();}程序运行后test1.txt的内容为:已成功写入文件!11-4使用I/O流以文本方式打开上一题建立的文件test1.txt,读出其内容显示出来,看看是否正确。解:#includevoidmain(){charch;ifstreamfile2("test.txt");while(file2.get(ch))cout< 课后答案网www.khdaw.comvoidmain(){ofstreamfile1("test.txt",ios::app);file1<<"已成功添加字符!";file1.close();charch;ifstreamfile2("test.txt");while(file2.get(ch))cout<classdog{public:dog(intweight,longdays):itsWeight(weight),itsNumberDaysAlive(days){}~dog(){}intGetWeight()const{returnitsWeight;}voidSetWeight(intweight){itsWeight=weight;}longGetDaysAlive()const{returnitsNumberDaysAlive;}voidSetDaysAlive(longdays){itsNumberDaysAlive=days;}private:intitsWeight; 课后答案网www.khdaw.comlongitsNumberDaysAlive;};intmain()//returns1onerror{charfileName[80];cout<<"Pleaseenterthefilename:";cin>>fileName;ofstreamfout(fileName);//ofstreamfout(fileName,ios::binary);if(!fout){cout<<"Unabletoopen"<usingnamespace::std;voidmain(){ios_base::fmtflagsoriginal_flags=cout.flags();//1cout<<812<<"|";cout.setf(ios_base::left,ios_base::adjustfield);//2cout.width(10);//3cout<<813<<815<<"n";cout.unsetf(ios_base::adjustfield);//4cout.precision(2);cout.setf(ios_base::uppercase|ios_base::scientific);//5cout<<831.0;cout.flags(original_flags);//6}解://1保存现在的格式化参数设置,以便将来恢复这些设置;//2把对齐方式由缺省的右对齐改为左对齐;//3把输出域的宽度由缺省值0改为10;//4清除对齐方式的设置;//5更改浮点数的显示设置;//6恢复原来的格式化参数设置。程序运行输出:812|8138158.31E+0211-8提示用户输入一个十进制整数,分别用十进制、八进制和十六进制形式输出。解: 课后答案网www.khdaw.com#includevoidmain(){intn;cout<<"请输入一个十进制整数:";cin>>n;cout<<"这个数的十进制形式为:"<#include#includevoidmain(intargc,char*argv[]){strstreamtextfile;{ifstreamin(argv[1]);textfile<classException 课后答案网www.khdaw.com{public:Exception(){}virtual~Exception(){}virtualvoidPrintError()=0;};classOutOfMemory:publicException{public:OutOfMemory(){}~OutOfMemory(){}virtualvoidPrintError();};voidOutOfMemory::PrintError(){cout<<"OutofMemory!!n";}classRangeError:publicException{public:RangeError(unsignedlongnumber){BadNum=number;}~RangeError(){}virtualvoidPrintError();virtualunsignedlongGetNumber(){returnBadNum;}virtualvoidSetNumber(unsignedlongnumber){BadNum=number;}private:unsignedlongBadNum;};voidRangeError::PrintError(){cout<<"Numberoutofrange.Youused"<>Number;if(Number>1000||Number<0)throwRangeError(Number);*p=Number;}程序运行输出:Enteraninteger(0~~1000):56Thenumberis:56Enteraninteger(0~~1000):2000 课后答案网www.khdaw.comNumberoutofrange.Youused2000!12-5练习使用try、catch语句,在程序中用new分配内存时,如果操作未成功,则用try语句触发一个字符型异常,用catch语句捕获此异常。解:#includevoidmain(){char*buf;try{buf=newchar[512];if(buf==0)throw"内存分配失败!";}catch(char*str){cout<<"有异常产生:"<classCException{public:CException(){};~CException(){};constchar*Reason()const{return"CException类中的异常。";}}; 课后答案网www.khdaw.comvoidfn1(){cout<<"在子函数中触发CException类异常"<

您可能关注的文档