C++课后习题解答.docx
《C++课后习题解答.docx》由会员分享,可在线阅读,更多相关《C++课后习题解答.docx(20页珍藏版)》请在冰点文库上搜索。
C++课后习题解答
第1章面向对象的方法学
1.什么是面向对象方法学
解:
面向对象方法学就是尽量模拟人类习惯的思维方式,使软件开发的方法与过程尽可能接近人类认识世界、解决问题的方法与过程,从而使描述问题的问题空间(即问题域)与实现解法的解空间(即求解域)在结构上尽可能一致。
2.什么是对象它与传统的数据有何关系有什么不同
解:
对象是封装了数据结构及可以施加在这些数据结构上的操作的封装体。
它与传统数据有本质的不同,传统数据是被动地等待对它进行处理,对象是进行处理的主体。
3.什么是封装性和继承性
解:
封装是面向对象方法的一个重要特点,即将对象的属性和行为封装在对象的内部,形成一个独立的单位,并尽可能隐蔽对象的内部细节。
继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。
4.什么是多态性
解:
多态性是面向对象方法的重要特征。
不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
5.试写出学生管理系统中所涉及的类(属性和方法)。
学生管理系统中学生信息有:
姓名、学号、年龄、成绩;学生管理系统完成学生信息输入、学生信息输出、插入学生信息、删除学生信息、查找学生信息。
[
解:
classStudent
{
private:
charcName[12];ETFramework之上的高级程序设计语言。
C#集C语言的简洁强大、C++的面向对象、VB的图形化设计方法、Java的编译与执行机制等优点于一身。
C#是创新性的新式编程语言,它巧妙地结合了最常用的行业语言和研究语言中的功能,并引入了多种潜在的新功能,提高了开发人员在语言构造方面的效率,将快速的应用程序开发与对底层平台各种功能的访问紧密结合在一起,使得程序员能够在.NET平台上快速开发各种应用程序。
7.C++支持多态性主要表现在哪些方面
解:
C++支持两种多态性,即编译时的多态性和运行时的多态性。
编译时的多态性是通过重载来实现的,运行时的多态性是通过虚函数来实现的。
思考题
1.设计一个栈类,实现的操作有初始化栈、入栈、出栈、判栈空。
解:
¥
classStack
{
private:
inttop;
ints[100];
public:
voidIni_Stack();3o<<""<}
2.定义一个图书类,图书信息有图书名称、作者、出版社、价格。
要求利用栈实现图书的入库、出库和显示等功能。
constintMAXSIZE=5;ame<<""<;
}
3.有Distance类和Point类,将Distance类定义为Point类的友元类来实现计算两点之间距离。
第5章静态与命名控制
1.下列静态数据成员的特性中,错误的是(D)。
A.说明静态数据成员时,前边要加关键字static
B.静态数据成员在类外进行初始化
C.引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符
!
D.静态数据成员不是所有对象所共有的
2.下列关于静态数据成员的叙述,错误的是(A)。
A.静态数据成员在对象调用析构函数后,从内存中撤销
B.即使没有实例化类,静态数据成员也可以通过类名进行访问
C.类的静态数据成员是该类所有对象所共享
D.类的静态数据成员需要初始化
3.下列关于静态成员的叙述中,错误的是(B)。
A.类的外部可以直接调用类的静态数据成员和静态成员函数
B.与一般成员一样,只有通过对象才能访问类的静态成员
C.类的静态数据成员不能在构造函数中初始化
@
D.类的一般成员函数可以调用类的静态成员
4.声明类的成员为静态成员,必须在其前面加上关键字(B)。
A.constB.staticC.publicD.virtual
5.静态成员为该类的所有(B)共享。
A.成员B.对象C.this指针D.友元
6.程序运行结果:
1
2
3
7.程序运行结果:
CStatic:
:
val=10
%
思考题
1.利用静态数据成员的概念,编写一个类,统计目前存在多少个该类的对象。
classA
{
private:
staticintn;
public:
A()
{
n++;
~
}
voidPrint()
{
cout<}
};
intA:
:
n=0;
intmain()
{
Aa1;
;
();
Aa[5],a2;
();
return0;
}
2.利用静态数据成员的概念,编写一个学生类,学生信息包括姓名、学号、成绩;统计学生的总人数及总成绩,并输出。
#include"iostream"
#include"iomanip"
usingnamespacestd;
classStudent
《
{
private:
char*name;
intstu_no;
floatscore;
staticinttotal_num;
staticfloattotal_score;
public:
Student(char*na,intno,floatsco);
voidPrint();
^
};
intStudent:
:
total_num=0;
floatStudent:
:
total_score=0;
intmain()
{
Students1("张明",1,90);
();
Students2("王兰",2,95);
();
·
Students3("于敏",3,87);
();
return0;
}
Student:
:
Student(char*na,intno,floatsco)
{
name=newchar[strlen(na)+1];
strcpy(name,na);
stu_no=no;
~
score=sco;
total_num++;
total_score=total_score+score;
}
voidStudent:
:
Print()
{
cout<<"第"<"<<cout<<"总人数是:
"<cout<<"总分数是:
"<-
}
3.利用静态的概念,编写一个小猫类,统计并输出每个小猫的重量、小猫的总数量及总重量。
classsmall_cat态绑定。
在运行时确定函数调用称为动态绑定。
2.如果A是从B继承而来,则A叫子类,B叫父类。
3.在多重派生过程中,如果想使公共的基类在派生时只有一个副本,则可以将这个基类声明为虚基类。
二、选择题
1.在类的继承与派生过程中,关于派生类不正确的说法是(B)。
A.派生类可以继承基类的所有特性B.派生类只能继承基类的部分特性
C.派生类可以重新定义已有的成员D.派生类可以改变现有成员的属性
2.派生类对象对它的基类成员,(A)是可以访问的。
)
A.公有继承的公有成员B.公有继承的私有成员
C.公有继承的保护成员D.私有继承的共有成员
3.下列叙述中不正确的是(C)。
A.含纯虚函数的类称为抽象类B.不能直接由抽象类建立对象
C.抽象类不能作为派生类的基类D.纯虚函数没有其函数的实现部分
4.当定义派生类的对象时,调用构造函数的正确顺序是(A)。
A.先调用基类的构造函数,再调用派生类的构造函数
B.先调用派生类的构造函数,再调用基类的构造函数
C.调用基类的构造函数和派生类的构造函数的顺序无法确定
D.调用基类的构造函数和派生类的构造函数是同时进行的
*
5.关于多重继承二义性的描述中,(D)是错误的。
A.一个派生类的两个基类中都有某个同名成员,在派生类中对这个成员的访问可能出现二义性
B.解决二义性最常用的方法是对成员名的限定
C.基类和派生类中出现同名函数,也存在二义性
D.一个派生类是从两个基类派生而来的,而这两个基类又有一个共同的基类,对该基类成员进行访问时,也可能出现二义性
6.派生类的构造函数的成员初始化列表中,不能包含(C)。
A.基类的构造函数B.派生类的自对象的初始化
C.基类的自对象的初始化D.派生类的一般数据成员的初始化
7.下列关于protected成员说法,正确的是(A)。
A.在派生类中仍然是protected的B.具有private成员和public成员的双重角色
.
C.在派生类中是private的D.在派生类中是public的
8.下列关于虚函数的说法,正确的是(C)。
A.虚函数是一个static类型的成员函数
B.虚函数是一个非成员函数
C.基类中采用virtual声明一个虚函数后,派生类中定义相同原型的函数时可以不加virtual声明
D.派生类中的虚函数与基类中相同原型的虚函数具有不同的参数个数或类型
9.关于虚函数和抽象类描述中,(C)是错误的。
A.纯虚函数是一种特殊的函数,它没有具体实现
B.抽象类是指具有纯虚函数的类
C.一个基类中声明有纯虚函数,则它的派生类一定不再是抽象类
】
D.抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出
10.下列程序,编译时出现错误的是(C)。
classA{1B.2C.3D.4
三、简答题
1.简要定义如下术语:
继承、虚函数、多重继承。
答:
继承性是自然界普遍存在的一种现象,是从先辈那里得到已有的特征和行为。
类的继承就是新类从已有类那里获得已有的属性和行为,或者说是基类派生了具有基类特征又有新特征的派生类。
虚函数需要在函数前面加virtual说明。
通过虚函数可以达到动态绑定效果。
在类的派生过程中,如果基类名有多个,则这种继承方式称为多继承,这时的派生类同时得到了多个已有类的特征。
"
2.分别说明什么是抽象基类什么是虚基类
当一个类中存在纯虚函数时,这个类就是抽象类。
如把一个基类定义为虚基类,必须在派生子类时在父类的名字前加关键字virtual。
第8章模板
1.类模板的使用实际上是将类模板实例化成为一个具体的(D)。
A.类B.对象C.函数D.模板类
2.关于类模板,下列表述中不正确的是(B)。
A.用类模板定义一个对象时,不能省略实参
B.类模板只能有虚拟类型参数
C.类模板本身在编译中不会生成任何代码
D.类模板的成员函数都是模板函数
3.类模板的模板参数(D)。
A.只可作为数据成员的类型B.只可作为成员的返回类型
C.只可作为成员函数的参数类型D.以上三者皆是
4.一个(D)允许用户为类定义一种模式,使得类中的某些数据成员及某些成员函数的返回值能取任意类型。
A.函数模板B.模板函数C.类模板D.模板类
5.如果一个模板声明列出了多个参数,则每个参数之间必须使用逗号隔开,每个参数都须重复使用关键字(D)。
A.constB.staticC.voidD.class
6.假设类模板Employee存在一个static数据成员salary,由该类模板实例化3个模板类,那么存在(D)个static数据成员的副本。
;
A.0B.1C.2D.3
7.程序运行结果:
120
思考题
1.编写一个使用类模板对数组进行排序、查找和求元素和的程序。
constintSIZE=10;.....输入链表"<cout<<"2.......输入链表"<cout<<"0.......退出"<cout<<"请选择"<cin>>n;
switch(n)
'
{
case1:
head1=newNode;
head1->next=0;
CreateLinkList(head1);
break;
case2:
head2=newNode;
head2->next=0;
CreateLinkList(head2);
%
}
}while(n);
}
template
voidLinkList:
:
Print_LinkList()
{
intn;
do
{
!
Node*p;
cout<<"1.......输出链表"<cout<<"2.......输出链表"<cout<<"3.......输出合并后的链表"<cout<<"0.......退出"<cout<<"请选择"<cin>>n;
switch(n)
{
case1:
-
p=head1->next;
break;
case2:
p=head2->next;
break;
case3:
Merge();
p=head3->next;
}
if(n)
|
{
while(p)
{
cout<data<<"";
p=p->next;
}
cout<}
}while(n);
}
#
template
voidLinkList:
:
CreateLinkList(Node*h)
{
intflag=-1,num=0;
Node*s,*r;
r=h;
Tx;
cout<<"pleaseinputavalue(-1end):
"<cin>>x;
.
while(x!
=flag)
{
s=newNode;
s->data=x;
r->next=s;
r=s;
cin>>x;
}
if(r!
=NULL)r->next=NULL;
}
/
template
voidLinkList:
:
Merge()
{
Node*p1;
Node*s,*r;
p1=head1->next;
Ta[Maxlen],b[Maxlen],c[Maxlen];
inti,j,k,l,n1,n2;
i=0;
…
n1=0;
n2=0;
while(p1)
{
a[i]=p1->data;
p1=p1->next;
i++;
n1++;
}
p1=head2->next;
|
i=0;
while(p1)
{
b[i]=p1->data;
p1=p1->next;
i++;
n2++;
}
i=n1-1;
j=n2-1;
%
k=0;
while(i>=0&&j>=0)
{
if(a[i]>b[j])
{
c[k++]=a[i--];
}
else
{
c[k++]=b[j--];
:
}
}
if(i>=0)
{
for(l=i;l>=0;l--)
c[k++]=a[l];
}
else
{
for(l=j;l>=0;l--)
)
c[k++]=b[l];
}
head3=newNode;
head3->next=0;
r=head3;
for(i=0;i{
s=newNode;
s->data=c[i];
r->next=s;
$
r=s;
}
if(r!
=NULL)r->next=NULL;
}
4.用类模板实现栈,功能有:
判断栈是否为空、入栈、出栈、读栈顶元素。
constintMAXSIZE=100;文件,它包含了所有输入/输出操作所需要的信息。
2.成员函数setf()和unsetf()被用来设置和恢复格式状态标志。
3.要格式化流操纵元,必须包含头文件。
流插入操作符是<<,流提取操作符是>>。
4.C++中,数据文件类型分为(C)。
A.文本文件和顺序文件B.顺序文件和随机文件
'
C.文本文件和二进制文件D.数据文件和文本文件
5.(A)是标准输入流。
A.cinB.coutC.cerrD.clog
6.关于提取和插入运算符,下列说法不正确的是(A)。
A.可以重载为类的成员函数
B.应该重载为类的友元函数
C.提取运算符是从输入字符序列中提取数据
D.插入运算符是把输出数据插入到输出字符序列中
7.选择下面程序的运行结果(D)。
#include<>
'
voidmain()
{
inti=100;
(ios:
:
hex);
cout<
cout<
(ios:
:
dec);
cout<
}
【
A.6410064
B.646464
C.6464100
D.64100100
8.判断正误,如果不正确,说明原因。
(1)带有long型参数的流成员函数flags()用于根据参数设置标志状态,并返回原来的设置。
(正确)
(2)流插入操作符<<和流读取操作符>>被重载以处理所有的标准数据——包括字符和内存地址(仅对流插入)——和全部用户自定义类型,而且可以作为成员函数定义。
(不正确)
9.下面程序运行后,数据文件保存的结果是(13579)。
#include
#include
;
usingnamespacestd;
intmain()
{
ofstreamoutf("");
inti;
for(i=1;i<10;i++){
if(i%2==0)
cout<
else
outf<
}
();
return0;
}
10-12.略
第10章异常处理
1.下面哪个throw表达式是错误的为什么C
A.classexceptionType{};
throwexceptionType();
B.intexcpObj;
throwexcpObj;
C.enummathErr{overflow,underflow,zerodivide};
throwzerodivide();
D.int*pi=&excpObj;
throwpi;
2.说明下面的函数可以抛出哪些异常。
D
A.voidoperate()throw(logic_error);
B.intop(int)throw(underflow_error,over_error);
C.charmanip(stirng)throw();
D.voidprocess();
3.如果try中不抛出异常,那么try块执行完后控制权会转向何处
答:
如果try块中的代码没有抛出异常,则立即跳过try块后面的所有catch异常处理程序,执行catch后面的第一条语句。
4.如果没有匹配出对象类型的catch处理程序,会发生什么情况
答:
如果找到类型匹配的catch语句进行捕获,其参数被初始化为指向异常对象,执行相应catch内的语句模块;如果找不到匹配类型的catch语句,系统函数terminate被调用,终止程序。
5.编写一个C++程序,演示重抛出异常。
答:
例10-1.
第11章-12章.略