第六章作业内容(答案)

  • 格式:doc
  • 大小:59.50 KB
  • 文档页数:17

第六章作业内容一、选择题1.运算符重载时不需要保持的性质是:( A )A.操作数类型B.操作数个数C.优先级D.结合性理由:操作数实际上对应的是重载函数的参数,按照重载函数的定义,其构成的条件是参数不同,对于运算符来说,要求其操作数个数必须相同,就是参数个数相同,因此就需要要求参数类型不同,即操作数类型不同。

2.在C++中,要实现动态联编,必须使用(D)调用虚函数。

A.类名B.派生类指针C.对象名D.基类指针理由:3. 有如下类定义和变量定义:#include<iostream.h>class X{int a;void setX (int x){a=x;}public:void showX(){cout<<"a="<<a<<endl;}};class Y: private X{/*类定义省略*/};class Z: public X{/*类定义省略*/};Y objY;Z objZ;下列语句中正确的是:( D )A.objY.setX(3);B.objY.showX();C.objZ.setX(4);D.objZ.showX();理由:因为类Y,Z对X的继承方式不同,Y对X 是私有继承,Z 对X 是公有继承,导致了X类的成员都是Y类的私有成员,而X 类的成员在Z类中的访问方式都和在X类中一样不变。

因此,setX、showX都是Y类的私有成员,所以Y类的对象objY不能直接访问setX、showX;setX是Z类的私有成员,showX是Z类的公有成员,所以Z类的对象objZ可以直接访问showX,而不能访问setX函数;4. 有如下类定义:#include<iostream.h>class A{ int xx;public:A():xx(0){cout<<'A';}A(int n):xx(n){cout<<'B';}};class B: public A{ int yy;public:B():yy(0){cout<<yy;}B(int n):A(n+1),yy(n){cout<<yy;}B(int m,int n):A(m),yy(n){cout<<yy;}};下列选项中,输出结果为A0的语句是:( D )A.B y1(0,0);B.B y2(1);C.B y3(0);D.B y4;理由:要使输出结果为A0,主要看定义的派生类对象B调用的是哪一个构造函数(基类和派生类),分析构造函数:基类构造函数中,默认构造函数输出“A”,即调用无惨构造函数派生类构造函数中,没有给基类传递参数的是默认构造函数,且输出“0”所以,定义对象的语句一定没有参数,即B y4;5.己知表达式a++中的“++”是作为友元函数重载的运算符,则与a++等效的运算符函数调用形式为:( C )A.a .orerator++(1);B.operator++(a);C.operator++(a, 0);D.a.operator++(a, 0 );理由:既然是友元函数,a++又是后置++运算符,所以其运算符重载函数有两个参数,一个是当前对象,一个是后置标志,多一个int类型参数。

调用的形式是:a++; 或operator++(a,0);所以,选择(C).其他选项:6.下列函数中,不能说明为虚函数的是(C)。

A.私有成员函数B.公有成员函数C.构造函数D.析构函数理由:7.以下基类中的成员函数,哪个表示纯虚函数(C)。

A.virtual void vf(int);B.void vf(int)=0;C.virtual void vf( )=0;D.virtual void vf(int){ } 理由:8.类定义如下。

class A{public:virtual void func1( ){ }virtual void func2( ){ }};class B:public A{public:void func1( ) {cout<<”class B func1”<<endl;}virtual void func2( ) {cout<<”class B func2”<<endl;}};则下面正确的叙述是(A)A.A::func2( )和B::func1( )都是虚函数B.A::func2( )和B::func1( )都不是虚函数C.B::func1( )是虚函数,而A::func2( )不是虚函数D.B::func1( )不是虚函数,而A::func2( )是虚函数理由:9.C++中多态性包括两种多态性:编译时的和运行时的,前者是通过______来实现的(A)A.函数和运算符的重载B.类继承关系C.虚函数D.抽象类理由:10.下列关于虚函数的说明中,正确的是(B)。

A.从虚基类继承的函数都是虚函数B.虚函数不能是静态成员函数C.只能通过指针或引用调用虚函数D.抽象类中的成员函数都是虚函数理由:11.下列运算符中,________运算符不能重载为成员函数。

C A.赋值运算符= B.函数调用运算符( ) C.输出运算符<< D.后置++理由:输出运算符<<的第一个操作数不是当前类的对象,按照C++语言规定,这种情况只能定义为友元运算符重载函数。

12.类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中的函数理由:二、问答题:1.是否使用了虚函数就能实现运行时的多态性?怎样才能实现运行时的多态性?答:不是。

首先要在基类中定义虚函数,并在其派生类中定义重名的虚函数。

派生类一定以公有方式继承了基类。

实现运行时的多态性时,必须使用基类类型的指针变量或引用,使该指针指向该基类的不同派生类的对象,并通过该指针指向虚函数,才能实现动态的多态性。

2.为什么析构函数总是要求说明为虚函数?答:在基类中及其派生类中都动态分配内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性。

根据赋值兼容规则可以用基类的指针指向派生类对象,如果由该指针撤销派生类对象,未将析构函数说明为虚函数,则会调用基类的析构函数,使对象释放不完全。

因此必须将析构函数说明为虚函数,实现多态性,自动调用派生类析构函数,使得所定义的派生类对象得到完全的释放。

3. 存在这样的抽象类吗?该类定义中并没有定义纯虚函数。

答:存在这样的抽象类,该类继承的基类中定义了纯虚函数,而该类定义中没有重新定义纯虚函数,但该类继承了纯虚函数,所以该类也存在纯虚函数,所以也是抽象类。

4.定义虚函数的目的是什么?定义纯虚函数有什么作用?答:定义虚函数的目的是实现动态多态性;作用是定义纯虚函数的目的在于基类给派生类提供一个标准的函数原型,统一接口,为实现动态多态性打下基础,派生类将根据需要给出纯虚函数的具体实现代码。

三、读程序按要求做题1.以下程序如果将Point类的析构函数定义为虚函数,输出结果是什么?试分析原因#include<iostream>using namespace std;class Point{public:Point(float a,float b):x(a),y(b){}~Point(){cout<<"executing Point destructor"<<endl;}private:float x;float y;};class Circle:public Point{public:Circle(int a,int b,int r):Point(a,b),radius(r){}~Circle (){cout<<"execting Circle destructor"<<endl;}private:float radius;};int main(){Point*p=new Circle(2.5,1.8,4.5);delete p;return 0;}原运行结果为:executing Point destructorPress any key to continue修改后运行结果为:execting Circle destructorexecuting Point destructorPress any key to continue原因:指针p是指向派生类的基类指针,在不生命析构函数为虚函数时,编译器实施静态绑定,在删除基类指针时,只调用指针所属的基类的析构函数,而不调用派生类的析构函数,析构不完全,出现最初的运行结果。

而将基类的析构函数声明为虚函数,删除该在指针时,就会实现动态多态性,调用该指针指向的派生类的析构函数,而派生类的析构函数又会自动调用基类的析构函数,使整个对象完全释放,出现修改后的运行结果。

2.找出下面程序运行结果错误的原因(未按++、--运算符的要求做),并改正。

#include<iostream.h>class coord{int x,y;public:coord(int i=0,int j=0);void print();friend coord & operator++(coord op);//};coord::coord(int i,int j){x=i;y=j;}void coord::print(){cout<<" x:"<<x<<",y:"<<y<<endl;}coord & operator ++(coord op)//{ ++op.x;++op.y;return op;}main(){ coord ob(10,20);ob.print();++ob;//ob.print();operator++(ob);//ob.print();return 0;答:错误在于++重载函数改变了原来的++应该实现的功能。

因为++运算的实际意义是改变其作用的变量(操作数)的值,所以一定要考虑传递的参数必须被改变(即必须是传地址(指针/引用)),否则就没有实现原来++的功能。

因此,该程序需要修改的语句为:friend coord & operator++(coord op); 修改为:friend coord & operator++(coord &op);coord & operator ++(coord op)// 修改为:coord & operator ++(coord &op)3.读下列程序,按要求做题#include<iostream.h>class B0{public:void display(){cout<<"B0::display()"<<endl;};};class B1:public B0{public:void display(){cout<<"B1::display()"<<endl;};};class D1:public B1{public:void display(){cout<<"D1::display()"<<endl;};};void main(){B0 b0,*p;B1 b1;D1 d1;p=&b0;p->display();p=&b1;p->display();p=&d1;p->display();}如果把B0修改如下:Class B0{public:void virtual display()=0;将主函数修改为:void main(){B0 *p;B1 b1;D1 d1;p=&b0;p->display();p=&b1;p->display();p=&d1;p->display();}运行结果结果分别为什么,并分析原因。