logo资料库

C++面向对象程序设计 课后答案 铁道出版社.docx

第1页 / 共53页
第2页 / 共53页
第3页 / 共53页
第4页 / 共53页
第5页 / 共53页
第6页 / 共53页
第7页 / 共53页
第8页 / 共53页
资料共53页,剩余部分请下载后查看
网址 http://www.nanshan.edu.cn/xxgc/showart.asp?art_id=13 网址 http://www.nanshan.edu.cn/xxgc/showart.asp?art_id=17 软件工程学院 http://www.nanshan.edu.cn/xxgc/index.asp 第一章:面向对象程序设计概述 [1_1]什么是面向对象程序设计? 面向对象程序设计是一种新型的程序设计范型。这种范型的主要特征是: 程序=对象+消息。 面向对象程序的基本元素是对象,面向对象程序的主要结构特点是:第一:程序一般由类的 定义和类的使用两部分组成,在主程序中定义各对象并规定它们之间传递消息的规律。第二: 程序中的一切操作都是通过向对象发送消息来实现的,对象接受到消息后,启动有关方法完 成相应的操作。 面向对象程序设计方法模拟人类习惯的解题方法,代表了计算机程序设计新颖的思维方式。 这种方法的提出是软件开发方法的一场革命,是目前解决软件开发面临困难的最有希望、最 有前途的方法之一。 [1_2]什么是类?什么是对象?对象与类的关系是什么? 在面向对象程序设计中,对象是描述其属性的数据以及对这些数据施加的一组操作封装在一 起构成的统一体。对象可以认为是:数据+操作 在面向对象程序设计中,类就是具有相同的数据和相同的操作的一组对象的集合,也就是说, 类是对具有相同数据结构和相同操作的一类对象的描述。 类和对象之间的关系是抽象和具体的关系。类是多个对象进行综合抽象的结果,一个对象是 类的一个实例。 在面向对象程序设计中,总是先声明类,再由类生成对象。类是建立对象的“摸板”,按照 这个摸板所建立的一个个具体的对象,就是类的实际例子,通常称为实例。 [1_3]现实世界中的对象有哪些特征?请举例说明。 对象是现实世界中的一个实体,其具有以下一些特征: (1)每一个对象必须有一个名字以区别于其他对象。 (2)需要用属性来描述它的某些特性。 (3)有一组操作,每一个操作决定了对象的一种行为。 (4)对象的操作可以分为两类:一类是自身所承受的操作,一类是施加于其他对象的操作。 例如:雇员刘名是一个对象 对象名:刘名 对象的属性: 年龄:36 生日:1966.10.1 工资:2000 部门:人事部 对象的操作:吃饭 开车 [1_4]什么是消息?消息具有什么性质? 在面向对象程序设计中,一个对象向另一个对象发出的请求被称为“消息”。当对象接收到 发向它的消息时,就调用有关的方法,执行相应的操作。消息是一个对象要求另一个对象执 行某个操作的规格的说明,通过消息传递才能完成对象之间的相互请求或相互协作。消息具 有以下 3 个性质: (1)同一个对象可以接收不同形式的多个消息,做出不同的响应。 (2)相同形式的消息可以传递给不同的对象,所做出的响应可以是不同的。 (3)消息的发送可以不考虑具体的接收者,对象可以响应消息,也可以不响应。 [1_5]什么是方法?消息和方法的关系是什么?
在面向对象程序设计中,要求某一对象作某一操作时,就向该对象发送一个响应的消息,当 对象接收到发向它的消息时,就调用有关的方法,执行响应的操作。方法就是对象所能执行 的操作。方法包括界面和方法体两部分。方法的界面也就是消息的模式,它给出了方法的调 用协议;方法体则是实现某种操作的一系列计算步骤,也就是一段程序。在 C++语言中方法 是通过函数来实现的,称为成员函数。消息和方法的关系是:对象根据接收到的消息,调用 相应的方法;反过来,有了方法,对象才能响应相应的消息。 [1_6]什么是封装和抽象?请举例说明。 在现实世界中,所谓封装就是把某个事物包围起来,使外界不知道该事物的具体内容。在面 向对象程序设计中,封装是指把数据和实现操作的代码集中起来放在对象内部,并尽可能隐 蔽对象的内部细节。对象好象是一个不透明的黑盒子,表示对象属性的数据和实现各个操作 的代码都被封装在黑盒子里,从外面是看不见的,更不能从外面直接访问或修改这些数据及 代码。使用一个对象的时候,只需要知道它向外界提供的接口形式而无需知道它的数据结构 细节和实现操作的算法。封装机制可以将对象的使用者与设计者分开,使用者不必知道对象 行为实现的细节,只需要使用设计者提供的接口让对象去做。 抽象是人类认识问题的最基本的手段之一。它忽略了一个主题中与当前目标无关的那些方面, 以便更充分地注意与当前目标有关的方面。抽象是对复杂世界的简单表示,抽象强调感兴趣 的信息,忽略了不重要的信息。例如,设计一个学籍管理程序的过程中,考察某个学生对象 时,只关心他的姓名、学好、成绩等,而对他的身高、体重等信息就可以忽略。以一般观点 而言,抽象是通过特定的实例(对象)抽象共同性质以后形成概念的过程。抽象是对系统的 简化描述或规范说明,它强调了系统中的一部分细节和特性,而忽略了其他部分。抽象包括 两个方面:数据抽象和代码抽象(或称为行为抽象)。前者描述某类对象的属性或状况,也 就是此类对象区别于彼类对象的特征物理量;后者描述了某类对象的共同行为特征或具有的 共同操作。 在面向对象程序设计方法中,对一个具体问题的抽象分析的结果,是通过类来描述和实现的。 现在以学生管理程序为例,通过对学生进行归纳、分析,抽取出其中的共性,可以得到如下 的抽象描述: 共同的属性:姓名、学号、成绩等,他们组成了学生数据抽象部分。用 C++语言的数据成员 来表示,可以是: char *name; int number; float score; 共同的行为:数据录入、数据修改和数据输出等,这构成了学生的行为抽象部分,用 C++语 言的成员函数表示,可以是:input();modify();print(); 如果我们开发一个学生健康档案程序, 所关心的特征就有所不同了。可见,即使对同一个研究对象,由于所研究问题的侧重点不同, 就可能产生不同的抽象结果。 [1_7]什么是继承?请举例说明。 继承所表达的是对象类之间的相关关系,这种关系使得某类对象可以继承另一类对象的特征 和能力。现实生活中,继承是很普遍和容易理解的。例如我们继承了父母的一些特征,如种 族、血型、眼睛的颜色等,父母是我们所具有的属性的基础。继承所表达的是对象之间相关 的关系。这种关系使得某一类可以继承另一个类的特征和能力。 [1_8]若类之间具有继承关系,则它们之间具有什么特征? (1)类间具有共享特征(包括数据和操作代码的共享) (2)类间具有差别或新增部分(包括非共享的数据和代码操作) (3)类间具有层次结构 假设有两个类 A 和 B,若类 B 继承类 A,则类 B 包含了类 A 的特征(包括数据和操 作),同时也可以加入自己所特有的新特性。这时,我们称被继承类 A 为基类或父类或超类;
而称继承类 B 为 A 类的派生类或子类。同时,我们还可以说,类 B 是从类 A 中派生出来的。 [1_9]什么是单继承、多继承?请举例说明。 从继承源上分,继承分为单继承和多继承。单继承是指每个派生类只直接继承了一个基 类的特征。多继承是指多个基类派生出一个派生类的继承关系。多继承的派生类直接继承了 不止一个基类的特征。例如:小孩的玩具车继承了车的一些特性,还继承了玩具的一些特征。 [1_10]什么是多态性?举例说明。 多态性也是面向对象程序设计的重要特性。它是指不同的对象收到相同的消息时产生不 同的行为方式。例如我们同样双击 windows 系统桌面上的图标时,有的是打开多媒体播放 器,有的是打开资源管理器。利用多态性,用户只需发送一般形式的消息,而将所有的实现 留给接收消息的对象。对象根据所收到的消息做出相应的动作。 [1_11]什么是函数重载和运算符重载?为什么要使用重载? 重载一般包括函数重载和运算符重载。函数重载是指一个表示符可同时用于为多个函数 命名,而运算符重载是指一个运算符可同时用于多种运算。也就是说,相同名字的函数或运 算符在不同的场合可以表现出不同的行为。 使用重载的目的是为了更好地表达行为共享,这种行为共享就象将相似的操作划分 在一起。使用重载可以使程序员在只知道操作的一般含义,而不知道操作的具体细节的情况 下能正确地对某个对象使用一个操作。另外,使用重载的直接益处是减少了程序员记忆操作 的名字的负担。 第二章::C++基础 [2_1]简述 C++的主要特点 (1)C++保持与 C 的兼容,用 C 编写的软件可以用到 C++中。 (2)用 C++编写的程序可读性好,代码结构更合理,可直接地在程序中映射问 题空间的结构。 (3)生成代码的质量高。 (4)软件的可重用性、可扩充性、可维护性和可靠性有了明显的提高,从而节省了开发费 用和时间。 (5)支持面向对象的机制,可方便地构造出模拟现实问题的实体和操作。 [2_2]下面是一个 C 程序,改写它,使它采用 C++风格的 i/o 语句 改写如下: #include main() { cout<<”enter two numbers: “; cin>>a; cin>>b; min=a>b?b:a; for(d=2;d
if((a%b)==0)&&((b%d)==0)) break; if(d==min) { return 0; cout<<”no common denominators\n”; } cout<<”the lowest common denominator is “<后加上语 句 sum(int a,int b);就可以通过了。 [2_5](1)答:这两个函数原形是等价的,因为函数原型中的参数名可以缺省。 (2)答:这两个函数的第一行是不等价的,函数的第一行中必须包含参数名。 (3)答:这两个函数原型是等价的,因为在函数原型中未注明参数,C++认为该函数的参数 表为空(void) [2_6]答:输出结果为:10 20 因为 f 函数的参数是引用,所以修改 k 的值有效。 函数调用后,主函数中 k 的值变为 10。由于 m 是对函数的引用,当 m 被赋 值为 20 时,k 的值也变为 20。 [2_7] 举例说明可以使用 const 替代#define 以消除#define 的不安全性 答:例如:#include #define A 2+4 #define B A*3 void main() { cout< const A=2+4; const B=A*3; void main() { cout< #include “stdio.h” void main() { int I,*p=new int[20];//动态分配 20 个整型空间 *p=1;
*(p+1)=1;//前面两个空间赋值 1 cout<<*p<<”\t”<<*(p+1)<<”\t”; p=p+2;//p 指向第三个空间 for(i=3;i<=20;i++) { *p=*(p-1)+*(p-2); cout<<*p<<”\t”; if(i%5==0) cout< #include int sroot(int );long sroot(long);double sroot(double); double sqrt();//声明开方函数 sqrt() void main() { int i,x;long l,y;double d,z; cin>>d; cin>>l; cin>>i; x=sroot(i); y=sroot(l); z=sroot(d); cout< void main() { int i,j,sum=0; for(i=0;i<=20;i++) for(j=0;j<=50;j++) if(100-5*i-2*j>=0) {
sum++; cout<<100-5*i-2*j<<”\t”< #include inline float f(float x) { void main() { return 2*x*x*x-4*x*x+3*x-6; } float left,right,middle,ym,yl,yr; cout<<”pleass two number:”<>left>>right; yl=f(left); yr=f(right); do { middle=(right+left)/2; ym=f(middle); if(yr*ym>0) { right=middle; Yr=ym; } else { left=middle; yl=ym; } }while(fabs(ym)>=1e-6); cout<<”\nRoot is:”<
int *p=new int[10](0)想给一个数组分配内存空间时,对整个数组进行初始化,这是不 允许的。 [2_17]答:D 说明:name 被定义为指向常量的常指针,所以它所指的内容和本 身的内容都不能修改,而 name[3]=’a’;修改了 name 所指的 常量,name=’lin’;和 name=new char[5];修改了常指针,只有 D 输出一个字符是正确的。 [2_18]答:A 说明:name 被定义指向常量的指针,这是一个不能移动的固定指针,它所指 的内容不能改变,但指针所指的数据可以改变,而 name[3]=’q’;修改了 name 所指的内容, 是正确的。name=”lin”; name=new char[5]; name=new char(‘q’);以不同的方法修改了常 指针,都是错误的。 [2_19]答:A 说明:name 被定义指向常量的指针,不允许改变指针所指的常量,但指针本 身的内容可以修改,而 name[3]=’q’;修改了 name 所指的内容,是错误的。name==”lin” name=new char[5];和 name=new char(‘q’)以不同的方法修改了常指针,都是正确的。 [2_20]答:D 说明:C++中不能建立引用数组和指向引用的指针,也不能建立引用的引用。 所以 A、B、C 是错误的,D 是正确的。 第三章:类和对象(一) [3_1]答:类声明的一般格式如下: class 类名 { public: 公有数据成员; 公有成员函数; protected: 保护数据成员; 保护成员函数; private: 私有数据成员; 私有成员函数; };其中:class 是声明类的关键字;类名是要声明的类的名字;后面的花括号表示出类声明 的范围;最后的分号表示类声明结束。 [3_2]答:构造函数是一种特殊的成员函数,它主要用于为对象分配空间,进行初始化。构 造函数具有一些特殊的性质: (1)构造函数的名字必须与类名相同 (2)构造函数可以有任意类型的参数,但不能指定返回类型。它有隐含的返回值,该值在 系统内部使用。 (3)构造函数是特殊的成员函数,函数体可写在类体内,也可写在类体外。 (4)构造函数可以重载,即一个类中可以定义多个参数个数或参数类型不同的构造函数。 (5)构造函数被声明为公有函数,但它不能象其它成员函数那样被显示地调用,它是在定 义对象的同时被调用的。 析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用
于撤消对象时的一些清理任务,如释放分配给对象的内存空间等。析构函数有以下一些特点: (1)析构函数与构造函数名字相同,但它前面必须加一个波浪号(~) (2)析构函数没有参数,不能指定返回类型,而且不能重载。因此在一个类中只能有一个 析构函数。 (3)当撤消对象时,编译系统会自动地调用析构函数。 [3_3]答:B 说明:C++中对构造函数有一些规定:不能带返回值;可以不带 参数;也可以缺省定义;但构造函数的名字与类名必须完全相同。 [3_4]答:C 说明:C++中没有限定 private、public、protected 的书写次序。但 是,不能在类的声明中给数据成员赋初值,数据成员的数据类型 也不能是 register(寄存器类型),没有用 private、public、protected 定义的数据成员是私有成员。 [3_5]答:C 说明:C++中对析构函数也有一些规定:没有参数;不能重载;析构函数的名 字是在类名前加“~”;析构函数不能指定返回类型。 [3_6]答:B 说明:构造函数的工作是在创建对象时执行的。 [3_7]答:语句”p1.age=30;”出现错误。因为 age 是私有数据成员,不能直接访问。 [3_8]答:第 1 个错误:printStu、setSno 两个成员函数没有用 public 定义,则不 允许外部函数对对象进行操作。 第 2 个错误:成员函数在类外定义,应加上类名“Student::”。 第 3 个错误:setAge 应在类中说明,并且在类外定义时,应加上类名”Student::”。 [3_9]答:语句”Point cpoint;”是错误的,它试图用私有的构造函数 Point 访问公有数据成员 x 和 y,这是不对的。 [3_10]答:语句 Stack stt;”应该带参数,因为当类中没有定义构造函数时,编译器会自动生 成一个缺省的不带参数的构造函数。但是,如果类中有自己定义的构造函数后,编译器将不 再自动生成一个缺省的构造函数。例如:将上述语句改成“Stack stt(10);”就正确了。 [3_11]:下面是一个计数器的定义,请完成该类成员函数的实现 #include class counter { public: counter(int number);//构造函数 void increment(); //给原值加 1 ///给原值减 1 void decrement(); //取得计数器值 int getvalue(); int print(); //显示计数 private: int value; value=number; }; counter::counter(int number)//构造函数定义 { void counter::increment()//给原值加 1 { void counter::decrement()//给原值减 1 { int counter::getvalue()//取得计数器值 { return value; value--; } value++; } } }
分享到:
收藏