c++面向对象课后答案第9章范本模板.docx
《c++面向对象课后答案第9章范本模板.docx》由会员分享,可在线阅读,更多相关《c++面向对象课后答案第9章范本模板.docx(24页珍藏版)》请在冰豆网上搜索。
c++面向对象课后答案第9章范本模板
1.概念填空题
1.1C++支持两种多态性,分别是编译时和运行时。
1.2在编译时就确定的函数调用称为静态联编 ,它通过使用函数重载,模板等 实现。
1.3在运行时才确定的函数调用称为动态联编,它通过虚函数 来实现。
1.4虚函数的声明方法是在函数原型前加上关键字virtual。
在基类中含有虚函数,在派生类中的函数没有显式写出virtual关键字,系统依据以下规则判断派生类的这个函数是否是虚函数:
该函数是否和基类的虚函数同名;是否与基类的虚函数参数个数相同、类型;是否与基类的虚函数相同返回类型。
如果满足上述3个条件,派生类的函数就是虚函数。
并且该函数覆盖基类的虚函数.
1.5当通过引用或指针使用虚函数时,C++会在与对象关联的派生类中正确的选择重定义的函数。
实现了运行时时多态。
而通过 对象使用虚函数时,不能实现运行时时多态.
1。
6纯虚函数是一种特别的虚函数,它没有函数的函数体部分,也没有为函数的功能提供实现的代码,它的实现版本必须由派生类给出,因此纯虚函数不能是友元函数 .拥有纯虚函数的类就是抽象类类,这种类不能 实例化。
如果纯虚函数没有被重载,则派生类将继承此纯虚函数,即该派生类也是抽象。
1.7类的构造函数不可以 (可以/不可以)是虚函数,类的析构函数可以(可以/不可以)是虚函数。
当类中存在动态内存分配时经常将类的 析构函数函数声明成虚函数 。
2.简答题
2.1在C++中,能否声明虚构造函数?
为什么?
能否声明虚析构函数?
为什么?
2.2什么是抽象类?
抽象类有何作用?
可以声明抽象类的对象吗?
为什么?
2。
3多态性和虚函数有何作用?
2.4是否使用了虚函数就能实现运行时的多态性?
怎样才能实现运行时的多态性?
2.5为什么析构函数总是要求说明为虚函数?
3.选择题
3。
1在C++中,要实现动态联编,必须使用(D)调用虚函数。
A。
类名 B。
派生类指针 C。
对象名 D.基类指针
3.2下列函数中,不能说明为虚函数的是(C)。
A。
私有成员函数 B.公有成员函数 C.构造函数 D.析构函数
3。
3在派生类中,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值(A).
A。
相同 B。
不同 C.相容 D.部分相同
3.4当一个类的某个函数被说明为virtual时,该函数在该类的所有派生类中(A).
A.都是虚函数
B.只有被重新说明时才是虚函数
C.只有被重新说明为virtual时才是虚函数
D.都不是虚函数
3.5(C)是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。
A.虚析构函数 B.虚构造函数
C.纯虚函数 D.静态成员函数
3.6以下基类中的成员函数,哪个表示纯虚函数(C)。
A.virtualvoidvf(int); B.voidvf(int)=0;
C.virtualvoidvf()=0; D.virtualvoidvf(int){}
3。
7下列描述中,(D)是抽象类的特性。
A.可以说明虚函数
B.可以进行构造函数重载
C.可以定义友元函数
D.不能定义其对象
3.8类B是类A的公有派生类,类A和类B中都定义了虚函数func(),p是一个指向类A对象的指针,则p->A:
:
func()将(A)。
A.调用类A中的函数func()
B.调用类B中的函数func()
C.根据p所指的对象类型而确定调用类A中或类B中的函数func()
D.既调用类A中函数,也调用类B中的函数
3。
9类定义如下。
classA{
public:
virtualvoidfunc1(){}
voidfun2(){}
};
classB:
publicA{
public:
voidfunc1(){cout<〈”classBfunc1”< virtualvoidfunc2(){cout〈〈”classBfunc2”〈};
则下面正确的叙述是(A)
A.A:
:
func2()和B:
:
func1()都是虚函数
B.A:
:
func2()和B:
:
func1()都不是虚函数
C.B:
:
func1()是虚函数,而A:
:
func2()不是虚函数
D.B:
:
func1()不是虚函数,而A:
:
func2()是虚函数
3。
10下列关于虚函数的说明中,正确的是(B)。
A.从虚基类继承的函数都是虚函数
B.虚函数不得是静态成员函数
C.只能通过指针或引用调用虚函数
D.抽象类中的成员函数都是虚函数
4.写出下列程序运行结果
4。
1#include〈iostream〉
usingnamespacestd;
classA{
public:
virtualvoidfunc(){cout〈<"funcinclassA”〈〈endl;}
};
classB{
public:
virtualvoidfunc(){cout<〈”funcinclassB”〈〈endl;}
};
classC:
publicA,publicB{
public:
voidfunc(){cout〈〈”funcinclassC”〈}
};
intmain(){
Cc;
A&pa=c;
B&pb=c;
C&pc=c;
pa。
func();
pb.func();
pc.func();
}
funcinclassC
funcinclassC
funcinclassC
4。
2#include〈iostream>
usingnamespacestd;
classA{
public:
virtual~A(){
cout〈〈”A:
:
~A()called“<};
classB:
publicA{
char*buf;
public:
B(inti){buf=newchar[i];}
virtual~B(){
delete[]buf;
cout〈〈”B:
:
~B()called”< }
};
voidfun(A*a){
deletea;
}
intmain()
{ A*a=newB(10);
fun(a);
}
B:
:
~B()called
A:
:
~A()called
5。
程序设计题
5。
1有一个交通工具类vehicle,将它作为基类派生小车类car、卡车类truck和轮船类boat,定义这些类并定义一个虚函数用来显示各类信息。
#include〈iostream>
#includeusingnamespacestd;
classVehicle{
public:
virtualvoidshowinfo()=0;
protected:
charName[20];
};
classCar:
publicVehicle{
public:
Car(char*name){
strcpy(Name,name);
}
voidshowinfo(){cout<protected:
intRadius;
};
classTruck:
publicVehicle{
public:
Truck(char*name){
strcpy(Name,name);
}
voidshowinfo(){cout<};
classBoat:
publicVehicle{
public:
Boat(char*name){
strcpy(Name,name);
}
voidshowinfo(){cout<};
intmain(){
Vehicle*vp;
Carcar(”奔驰");
Trucktruck("运输卡车");
Boatboat("游艇");
vp=&car;
vp—〉showinfo();
vp=&truck;
vp-〉showinfo();
vp=&boat;
vp->showinfo();
return0;
}
5.2定义一个shape抽象类,派生出Rectangle类和Circle类,计算各派生类对象的面积Area().
#include
#include〈cstring〉
usingnamespacestd;
classShape{
public:
virtualvoidArea()=0;
};
classRectangle:
publicShape{
public:
Rectangle(doublew,doubleh){
width=w,height=h;
}
voidArea(){cout<protected:
doublewidth,height;
};
classCircle:
publicShape{
public:
Circle(doubler){
radius=r;
}
voidArea(){cout〈<3.1415*radius*radius〈protected:
doubleradius;
};
intmain(){
Shape*sp;
Rectanglere1(10,6);
Circlecir1(4。
0);
sp=&re1;
sp->Area();
sp=&cir1;
sp—〉Area();
return0;
}
5.3定义猫科动物Animal类,由其派生出猫类(Cat)和豹类(Leopard),二者都包含虚函数sound(),要求根据派生类对象的不同调用各自重载后的成员函数.
#include〈iostream>
#include
usingnamespacestd;
classAnimal{
public:
virtualvoidSpeak()=0;
};
classCat:
publicAnimal{
voidSpeak(){
cout<<”MynameisCat"<〈endl;
}
};
classLeopard:
publicAnimal{
voidSpeak(){
cout<<”MynameisLeopard"〈 }
};
intmain(){
Animal*pa;
Catcat;
pa=&cat;
pa->Speak();
Leopardleopard;
pa=&leopard;
pa—〉Speak();
return0;
}
5.4矩形法(rectangle)积分近似计算公式为:
Δx(y0+y1+…。
yn-1)
梯形法(1adder)积分近似计算公式为:
[y0+2(y1+…。
yn-1)+yn]
辛普生法(simpson)积分近似计算公式(n为偶数)为:
[y0+yn+4(y1+y3…。
yn-1)+2(y2+y4+…yn-2)]
被积函数用派生类引入,定义为纯虚函数。
基类(integer)成员数据包括积分上下限b和a,分区数n,步长step=(b-a)/n,积分值result.定义积分函数integerate()为虚函数,它只显示提示信息。
派生的矩形法类(rectangle)重定义integerate(),采用矩形法做积分运算。
派生的梯形法类(1adder)和辛普生法(simpson)类似。
试编程,用3种方法对下列被积函数进行定积分计算,并比较积分精度。
(1)sin(x),下限为0。
0,上限为pir/2。
(2)exp(x),下限为0。
0,上限为1。
0。
(3)4。
0/(1+x×x),下限为0。
0,上限为1。
0.
解法一
#include#include〈cmath〉
usingnamespacestd;
classInteger{
protected:
doubleresult,a,b,step;//Intevalue积分值,a积分下限,b积分上限
intn;
public:
virtualdoublefun(doublex)=0;//被积函数声明为纯虚函数
virtualvoidIntegerate(){
cout<〈”这里是积分函数”< }
Integer(doublera=0,doublerb=0,intnn=2000){
a=ra;
b=rb;
n=nn;
result=0;
}
voidPrint(){
cout.precision(15);
cout<<"积分值=”< }
};
classRectangle:
publicInteger{
public:
voidIntegerate(){
inti;
step=(b-a)/n;
for(i=0;i<=n;i++)result+=fun(a+step*i);
result*=step;
}
Rectangle(doublera,doublerb,intnn):
Integer(ra,rb,nn){}
};
classLadder:
publicInteger{
public:
voidIntegerate(){
inti;
step=(b—a)/n;
result=fun(a)+fun(b);
for(i=1;i result*=step/2;
}
Ladder(doublera,doublerb,intnn):
Integer(ra,rb,nn){}
};
classSimpson:
publicInteger{
public:
voidIntegerate(){
inti;
step=(b-a)/n;
result=fun(a)+fun(b);
for(i=1;i for(i=2;i result*=step/3;
}
Simpson(doublera,doublerb,intnn):
Integer(ra,rb,nn){}
};
classsinR:
publicRectangle{//矩形法和梯形法采用并列结构
public:
sinR(doublera,doublerb,intnn):
Rectangle(ra,rb,nn){}
doublefun(doublex){returnsin(x);}
};
classsinL:
publicLadder{
public:
sinL(doublera,doublerb,intnn):
Ladder(ra,rb,nn){}
doublefun(doublex){returnsin(x);}
};
classexpR:
publicRectangle{
public:
expR(doublera,doublerb,intnn):
Rectangle(ra,rb,nn){}
doublefun(doublex){returnexp(x);}
};
classexpL:
publicLadder{
public:
expL(doublera,doublerb,intnn):
Ladder(ra,rb,nn){}
doublefun(doublex){returnexp(x);}
};
classotherR:
publicRectangle{
public:
otherR(doublera,doublerb,intnn):
Rectangle(ra,rb,nn){}
doublefun(doublex){return(4.0/(1+x*x));}
};
classotherL:
publicLadder{
public:
otherL(doublera,doublerb,intnn):
Ladder(ra,rb,nn){}
doublefun(doublex){return(4.0/(1+x*x));}
};
classsinS:
publicSimpson{//辛普生法采用层次结构
public:
sinS(doublera,doublerb,intnn):
Simpson(ra,rb,nn){}
doublefun(doublex){returnsin(x);}
};
classexpS:
publicsinS{
public:
expS(doublera,doublerb,intnn):
sinS(ra,rb,nn){}
doublefun(doublex){returnexp(x);}
};
classotherS:
publicexpS{
public:
otherS(doublera,doublerb,intnn):
expS(ra,rb,nn){}
doublefun(doublex){return(4。
0/(1+x*x));}
};
intmain(){
Integer*bp;
sinRsr(0。
0,3.1415926535/2。
0,100);
bp=&sr;
bp—〉Integerate();//动态,可以访问派生类定义的被积函数
bp—>Print();
sinLsl(0。
0,3。
1415926535/2.0,100);
bp=&sl;
bp—〉Integerate();//动态,可以访问派生类定义的被积函数
bp—>Print();
sinSss(0.0,3.1415926535/2。
0,100);
bp=&ss;
bp—〉Integerate();//动态,在层次中选
bp->Print();
expRer(0。
0,1.0,100);
bp=&er;
bp—〉Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
expLel(0.0,1。
0,100);
bp=&el;
bp—〉Integerate();//动态,可以访问派生类定义的被积函数
bp—〉Print();
expSes(0.0,1。
0,100);
bp=&es;
bp—〉Integerate();//动态,在层次中选
bp->Print();
otherRor(0。
0,1。
0,100);
bp=&or;
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp—>Print();
otherLol(0.0,1。
0,100);//增加到100000也达不到辛普生法的精度
bp=&ol;
bp—>Integerate();//动态,可以访问派生类定义的被积函数
bp—〉Print();
otherSos(0。
0,1。
0,100);
bp=&os;
bp-〉Integerate();//动态,在层次中选
bp—>Print();
return0;
}
解法二
//Integer为抽象类,fun为被积函数,其余3个虚函数为积分函数
#include#include
usingnamespacestd;
classInteger{
protected:
doubleresult,a,b,step;//Intevalue积分值,a积分下限,b积分上限
intn;
public:
virtualdoublefun(doublex)=0;//被积函数声明为纯虚函数
virtualvoidRectangle()=0;
virtualvoidLadder()=0;
virtualvoidSimpson()=0;
Integer(doublera=0,doublerb=0,intnn=2000){
a=ra;
b=rb;
n=nn;
step=(b—a)/n;
result=0;
}
voidPrint(){
cout。
precision(15);
cout<〈"积分值=”< }
};
classSIN:
publicInteger{
public:
SIN(doublera,doublerb,intnn):
Integer(ra,rb,nn){}
doublefun(doublex){returnsin(x);}
voidRectangle(){
inti;
for(i=0;i〈=n;i++)result+=fun(a+step*i);
result*=step;
}
voidLadder(){
inti;
result=fun(a)+fun(b);
for(i=1;i result*=step/2;
}
voidSimpson(){
inti;
result=fun(a)+fun(b);
for(i=1;i for(i=2;i result*=step/3;
}
};
intmain(){
Integer*Inp;
SINs(0,3。
1415926,1000);
Inp=&s;
Inp->Rectangle();
Inp—〉Print();
Inp-〉