C++作业题(8)一.选择填空(1) 定义重载函数的下列条件中,(C )是错误的。
A. 要求参数个数不同B. 要求参数类型不同C. 要求函数返回值类型不同D. 要求在参数个数相同时,参数类型的顺序不同(2) 关于下列虚函数的描述中,( C)是正确的。
A. 虚函数是一个static存储类的成员函数B. 虚函数是一个非成员函数C. 基类中说明了虚函数后,派生类中可不必将对应的函数说明为虚函数D. 派生类的虚函数与基类的虚函数应具有不同的类型或个数(3) 关于纯虚函数和抽象类的描述中,(C )是错误的。
A. 纯虚数是一种特殊的虚函数,它没有具体实现B. 抽象类中一定具有一个或多个纯虚函数C. 抽象类的派生类中一定不会再有纯虚函数D. 抽象类一般作为基类使用,使纯虚函数的实现由其派生类给出(4) 以下一种类中,( A)不能建立对象。
A. 抽象类B. 派生类C. 虚基类D. 基类(5)下列函数中不能重载的是( C )。
A)成员函数 B)非成员函数 C)析构函数 D)构造函数(6)下列描述中,抽象类的特征有( D )。
A)可以说明虚函数 B)可以构造函数重载 C)可以定义友员函数 D)不能说明其对象(7)下列不属于动态联编实现的条件有( D )。
A)要有说明的虚函数。
B)调用虚函数的操作是指向对象的指针或者对象引用:或者是由成员函数调用虚函数。
C)子类型关系的确立。
D)在构造函数中调用虚函数。
(8)派生类中对基类的虚函数进行替换时,派生类中说明的虚函数与基类中的被替换的虚函数之间不要求满足的是( C )。
A)与基类的虚函数具有相同的参数个数。
B)其参数的类型与基类的虚函数的对应参数类型相同。
C)基类必须定义纯虚函数。
D)其返回值或者与基类的虚函数相同,或者都返回指针或引用,并且派生类虚函数所返回的指针或引用的基类型是基类中被替换的虚函数所返回的指针或引用的基类的子类型。
(9)下列关于抽象类说法正确的是:( B )A)抽象类处于继承类层次结构的较下层。
B)抽象类刻画了一组子类的操作通用接口。
C)抽象类可以作为类直接使用。
D)抽象类可以直接定义对象。
(10)下列关于虚析构函数说法不正确的是( B )。
A)在析构函数前加上关键字virtual,就说明了虚析构函数。
B)如果一个基类的析构函数说明为虚析构函数,则它的派生类中的析构函数须用virtual 关键字说明后才是虚析构函数。
C)说明虚析构函数的目的在于使用delete删除一个对象时,能保证析构函数被正确地执行。
D)设置虚函数后,可以采用动态联编的方式选择析构函数。
(11)编译时多态性通过使用( B )获得。
A)继承 B)虚函数 C)重载函数 D)析构函数(12)可以使用( A )来阻止基类的成员函数调用派生类中的虚函数。
A)成员名限定 B)指针 C)引用 D)关键字virtual(13)抽象类应该含有( D )。
A)至多一个虚函数 B)至多一个虚函数是纯虚函数C)至少一个虚函数 D)至少一个虚函数是纯虚函数(14)一个抽象类可以说明为( A )。
A)指向抽象类对象的指针 B)类成员数据 C)抽象类的对象 D)数组元素(15)对于抽象类的使用需要注意的地方,下列不正确的说法是:( C )A)抽象类只能用作其它类的基类,不能建立抽象类对象。
B)抽象类不能用作参数类型,函数返回类型或显式转换的类型。
C)定义抽象类时至少要定义一个虚函数。
D)可以说明指向抽象类的指针和引用,此指针可以指向它的派生类,进而可以实现多态性。
(16)关于动态联编的说法,下列哪个不正确( C )A)动态联编只能通过指针或引用标识对象来操作虚函数。
B)C++使用虚函数来指定哪些函数需要用动态联编方式处理。
C)动态联编不能实现静态类型检查。
D)动态联编能够在运行时根据其类型确认调用哪个函数。
(17)将一个类的成员函数尽可能地设置成虚函数总是有益的,下列设置虚函数必须注意的情况中,哪个是错误的( D )A)只有类的成员函数才能说明为虚函数。
B)静态成员函数不能是虚函数。
C)构造函数不能是虚函数。
D)析构函数不能是虚函数。
(18)在派生类中重新定义虚函数时必须在( A )方面与基类保持一致。
A)参数个数 B)赋值 C)参数名字 D)操作内容(19)以下哪个基类中的成员函数表示纯虚函数( C )。
A)virtual void vf(int) B)void vf(int)=0; C)virtual void vf( )=0 D)virtual void vf(int){}(20)通过一个对象调用虚函数时,C++系统对该调用采用( B )。
A)动态联编 B)静态联编 C)不确定是哪种联编 D)函数重载参考答案:CCCAC DDCBB BADAC CDACB二.判断正误(1) 函数参数个数和类型都相同,只是返回值类型不同,这不是重载函数。
(×)(2)虚函数是为实现某种功能而假设的函数,派生类的虚函数定义影响其基类,而基类的虚函数定义不影响其派生类。
(×)(3)可以在类的内部说明虚函数,这时就可以定义一个虚的内联函数。
(√)(4)空的虚函数与纯虚函数都没有函数体,因此空的虚函数与纯虚函数在概念上是一样的,只是叫法不一样。
(×)(5)只要基类的析构函数被说明为虚函数,则派生类的析构函数,无论是否使用virtual进行说明,都自动地成为虚构函数。
(√)(6)虚函数是一种virtual说明的成员函数。
(√)(7)抽象类中只能有一个纯虚函数。
(×)(8)析构函数不能说明为虚函数。
(×)(9)程序中可以说明抽象类的指针或引用,但是不能说明抽象类的对象。
(√)参考答案:××√×√√××√三.分析程序运行结果1.#include<>class base{public:base(void){fc();}virtual void fc(void){cout<<"In class base"<<endl;}virtual ~base()=0{cout<<"Destructing base object..."<<endl;}};class A:public base{public:A(void){fc();}void f(void){fc();}~A(void){fd();}void fd(void){cout<<"Destructor A object..."<<endl;}};class B:public A{public:B(void){};void fc(void){cout<<"In class B"<< endl;}~B(void){fc();}void fd(void){cout<<"Destructor B object"<<endl;}};void main(void){B b;/*由于B类是A类的子类,A类是base类的子类,所以先调用base类的构造函数,再调用A类和B类的构造函数*/cout<<endl;(); .Destructing base object...In class BDestructor A object...Destructing base object...(2)#include<>class C;class A{public :int a;A(int i){a=i;}virtual void printOn(C&);};class B:public A{public:int b;B(int i,int j):A(i){b=j;}virtual void printOn(C&);};class C{friend void A::printOn(C&);friend void B::printOn(C&);int a,b,c;public:C(int i,int j,int k){a=i;b=j;c=k;} };void A::printOn(C& t){cout<<"Class A member a="<<a <<endl;cout<<"Class C member c="<< <<endl; }void B::printOn(C& t){cout<<"Class B member b="<<b<< endl;cout<<"Class C member c="<<<< endl;}void main(){//考查内容:指向基类对象的指针,可以指向其子类对象,// 使用指针调用成员函数时,根据对象不同而调用基类与其子类中相应的同名函数A a(10);B b(10,20);C c(10,20,30);A *p;p=&a;p->printOn(c);p=&b;p->printOn(c);}参考答案:Class A member a=10Class C member c=30Class B member b=20Class C member c=30(3)#include<>class base{public:virtual void a(){cout<<"a() in base\n";} virtual void b(){cout<<"b() in base\n";} virtual void c(){cout<<"c() in base\n";} virtual void d(){cout<<"d() in base\n";} virtual void e(){cout<<"e() in base\n";} virtual void f(){cout<<"f() in base\n";} };class A:public base{public:virtual void a(){cout<<"a() in A\n";}virtual void b(){cout<<"b() in A\n";}virtual void f(){cout<<"f() in A\n";} };class B:public base{public:virtual void a(){cout<<"a() in B\n";}virtual void b(){cout<<"b() in B\n";}virtual void c(){cout<<"c() in B\n";} };class C:public A,public B{public:virtual void a(){cout<<"a() in C\n";}virtual void d(){cout<<"d() in C\n";}};void main(){C cc;A *pa=&cc;pa->a(); //C类中有a(),调用pa->b(); //C类中没有b(),从其基类中寻找,先从A类中找,有则调用,无有则从B类中寻找pa->c(); //C类中没有c(),从其基类A和B中寻找,先从A类及其基类中找,有则调用;若无,则从B类及其基类中寻并调用pa->d(); //C类中有d(),调用pa->e(); //C类中没有e(),先从A类及其基类base中寻找,从base中找到,调用pa->f(); //C类中没有f(),先从A类及其基类base中寻找,在A类中找到并调用//考查内容:多态性,指向基类对象的指针可以指向其子类对象// 这种指针调用函数时先从子类中寻找,如果有则调用,如果没有则从基类中寻找}参考答案:a() in Cb() in Ac() in based() in Ce() in basef() in A(4)#include<>#include<>class A{public:A(){}virtual void func( ){cout<<"Constructing A"<<endl;} ~A( ){}virtual void fund( ){cout<<"Destructor A"<<endl;} };class B:public A{public :B( ){func();}virtual void func(){cout<<"Constructing B"<<endl;} void fun( ){func();}~B(){fund();}};class C: public B{public:C( ){}void func(){cout<<"Class C"<<endl;}~C(){fund();}void fund( ){cout<<"Destructor C"<<endl;}};void main(){C c; //分别调用A B C类的构造函数(); //先从C类中查找,没有则从其直接基类B中查找,找到并调用//构造函数调用函数 C B A}参考答案:Constructing BClass CDestructor CDestructor A(5) #include <>#include <>class base{char *p;public:base(int sz, char *bptr){p = new char [sz];strcpy( p, bptr);cout<<"constructor base"<<endl;}virtual ~base(){delete []p;cout << "destructor base\n";}};class derive: public base{char *pp;public:derive(int sz1, int sz2, char *bp,char *dptr) : base(sz1, bp) {pp = new char [sz2];strcpy( pp, dptr);cout<<"constructor derive"<<endl;}~derive(){delete [ ]pp;cout << "destructor derive\n";}};void main(){base *px=new derive(5,7,"base", "derive");delete px;}constructor baseconstructor derivedestructor derivedestructor base四.指出下列程序中的错误#include <>class A{public:virtual void f1(){ cout<<"A::f1()"<<endl; } virtual void f2(){cout<<"A::f2()"<<endl;}};struct B: A{void f1(){cout<<"B::f1()"<<endl; }void f2(int i){ cout<<"B::f2() "<<i<<endl; }}; void main(){ A *p;p=new A;p->f1(); p->f2();p=new B;p->f1(); p->f2(3);void (A::*pa)()=A::f1;p->*pa();B b;(); }五.程序设计(1)定义一个Shape类为抽象类,其中定义一个求面积的纯虚函数,从它派生出三角形(triangle)、矩形(rectangle)、圆(circle)三个子类,每个子类有各自不同的计算面积的公式:三角形(底*高*)、矩形(长*宽)、圆(*R*R)。