1、国家二级 C+机试(继承和派生)模拟试卷 13及答案解析(总分:52.00,做题时间:90 分钟)一、选择题(总题数:26,分数:52.00)1.建立一个有成员对象的派生类对象时,各构造函数体的执行次序为( )。(分数:2.00)A.派生类、成员对象类、基类B.成员对象类、基类、派生类C.基类、成员对象类、派生类D.基类、派生类、成员对象类2.有如下类定义和变量定义: class Parents public: int publicData; private: int privateData; ; class ChildA:public Parents*类体略*; class ChildB:p
2、rivate Parents*类体略*; ChildA a; ChildB b; 下列语句中正确的是( )。(分数:2.00)A.coutapublicDataendl;B.coutaprivateDataendl;C.coutbpublicDataendl;D.coutbprivateDataendl;3.通过派生类的对象可直接访问其( )。(分数:2.00)A.公有继承基类的公有成员B.公有继承基类的私有成员C.私有继承基类的公有成员D.私有继承基类的私有成员4.有如下程序: #includeiostream using namespace std; class AA int k; pro
3、tected: int n; void setK(int k)this-k=k; public: void setN(int n)this-n=n; ; class BB:public AA*类体略*; int main() BB x; xn=1;1 xsetN(2); 2 xk=3; 3 x.setK(4); 4 return 0; 在标注号码的四条语句中正确的是( )。(分数:2.00)A.1B.2C.3D.45.有如下两个类定义 class xx private: double x1; protected: double:x2; public: double x3; ; class YY
4、:protected XX private: double y1; potected: double y2; public: double y3; ; 在类 YY中保护成员变量的个数是( )。(分数:2.00)A.1B.2C.3D.46.有如下程序: #includeiostream using namespace std; class Music public: void setTitle(char*str)strcpy(title,str); protected: char type10; private: char title20; class Jazz:public Music pub
5、lic: void set(char*str) strcpy(type,Jazz); strcpy(title,str); ; 下列叙述中正确的是( )。(分数:2.00)A.程序编译正确B.程序编译时语句出错C.程序编译时语句出错D.程序编译时语句和都出错7.当派生类从一个基类保护继承时,基类中的一些成员在派生类中成为保护成员,这些成员在基类中原有的访问属性是( )。(分数:2.00)A.任何B.公有或保护C.保护或私有D.私有8.下列关于派生类和基类的描述中,正确的是( )。(分数:2.00)A.派生类成员函数只能访问基类的公有成员B.派生类成员函数只能访问基类的公有和保护成员C.派生类成
6、员函数可以访问基类的所有成员D.派生类对基类的默认继承方式是公有继承9.有如下类定义: class B public:void fun1() private:void fun2() protected:void fun3() ; class D:public B protected:void fun4() ; 若 obj是类 D的对象,则下列语句中不违反访问控制权限的是( )。(分数:2.00)A.pbj.fun1();B.objfun2();C.objfun3();D.objfun4();10.有如下程序: class Base public: int data; ; class Deriv
7、edl:public Base f; ; class Derived2:protected Base; int main() Derivedl d1; Derived2 d2; d1data=0; d2data=0; return 0; 下列关于程序编译结果的描述中,正确的是( )。(分数:2.00)A.皆无编译错误B.有编泽错误,无编译错误C.无编译错误,有编译错误D.皆有编译错误11.有如下程序: #includeiostream using namespace std; class xx int x; public: XX(int xx=0):x(xx) int getX()return
8、 x; ; class YY:public xx int y; public: YY(int xx,int yy):XX(xx),y(yy) int getV()return getX()+y; ; int main() YY c(3,4); coutcgetV()+cgetX()endl; return 0; 运行这个程序的输出结果是( )。(分数:2.00)A.3B.4C.7D.1012.有如下程序: #includeiostream using namespace std; class Media public: void Name();void Show(); protected: i
9、nt page; ; class Book:private Mediapublic: void Print() coutpageendl; void Show()Media:Show(); ; int main() Book Bible; BibleName(); Bible.Print(); Bible:Show(); return 0; 编译时有错误的是( )。(分数:2.00)A.语句B.语句C.语句D.语句13.有如下程序: #includeiostream using namespace std; class A public: A()coutA; ; classBpublic:B(
10、)coutB; classC:public A B b; public: C()coutC; ; int main()C obj;return 0; 执行后的输出结果是( )。(分数:2.00)A.CBAB.BACC.ACBD.ABC14.有如下程序: #includeiostream using namespace std; class A public: A()coutA; A()coutA; ; class B:public A A*p; public: B()coutB;p=new A(); B()coutBt;delete p; ; int main() B obj; return
11、0; 执行这个程序的输出结果是( )。(分数:2.00)A.BAAABAB.ABABAAC.BAABAAD.ABAABA15.有如下程序 #includeiostream using namespace std; class Base protected: Base()coutA; Base(char c)coutc; ; class Derived:public Base public: Derived(char c)coutc; ; int main() Derived dl(B); return 0; 执行这个程序屏幕上将显示输出( )。(分数:2.00)A.BB.BAC.ABD.BB1
12、6.在一个派生类对象结束其生命周期时( )。(分数:2.00)A.先调用派生类的析构函数后调用基类的析构函数B.先调用基类的析构函数后调用派生类的析构函数C.如果基类没有定义析构函数,则只调用派生类的析构函数D.如果派生类没有定义析构函数,则只调用基类的析构函数17.下列关于派生类构造函数和析构函数的说法中,错误的是( )。(分数:2.00)A.派生类的构造函数会隐含调用基类的构造函数B.如果基类中没有缺省构造函数,那么派生类必须定义构造函数C.在建立派生类对象时,先调用基类的构造函数,再调用派生类的构造函数D.在销毁派生类对象时,先调用基类的析构函数,再调用派生类的析构函数18.下列有关继承
13、和派生的叙述中,正确的是( )。(分数:2.00)A.派生类不能访问基类的保护成员B.作为虚基类的类不能被实例化C.派生类应当向基类的构造函数传递参数D.虚函数必须在派生类中重新实现19.有如下程序: #includeiostream using namespace std; class A public: A(int i)x=i; void dispa,()coutx,; private: int x; ; class B:public A public: B(int i):A(i+10)x=i; void dispb()dispa();coutxendl;private int x: ;
14、int main() B b(2); bdispb(); return 0; 运行时输出的结果是( )。(分数:2.00)A.10,2B.12,10C.12,2D.2,220.有如下程序: #includeiostream using namespace std; class Base int x; public; Baseint n=0;x(n)coutn; Int getX()constreturn x; ; class Derived public Base int y; public; Derived(int m,int n):y(rn),Base(n)coutm; Derived(i
15、nt m):y(m)coutm; ; int main() Derived dl(3),d2(5,7); return 0; 运行时的输出结果是( )。(分数:2.00)A.375B.357C.0375D.035721.有如下程序: #includeiostream using namespace std; class AA public: AA()cout1; ; class BB:public AA int k: public: BB():k(0)cout2; BB(int n):k(n)cout3; ; int main() BB b(4),c; return 0; 运行时的输出结果是(
16、 )。(分数:2.00)A.1312B.132C.32D.141222.有如下程序: #includeiostream using namespace std; class C1 public: C1()cout1; ; class C2:public C1 public: C2()cout2; ; int main() C2 cb2; C1*cb1; return 0; 运行时的输出结果是( )。(分数:2.00)A.121B.21C.211D.1223.有如下程序: #includeiostream using namespace std; class Base public: Base(
17、int x=0):valB(x)coutvalB; Base()coutvalB; private: int valB; ; class Derived:public Base public: Derived(int x=0,int y=0):Base(x),valD(y)coutvalD; Derived()coutvalD; private: int valD; ; int main() Derived obj 12(2,3); return 0; 运行时的输出结果是( )。(分数:2.00)A.2332B.2323C.3232D.322324.生成派生类对象时,派生类构造函数调用基类构造
18、函数的条件是( )。(分数:2.00)A.无需任何条件B.基类中显示定义了构造函数C.派生类中显式定义了构造函数D.派生类构造函数明确调用了基类构造函数25.有如下类定义: class AA int a; Publie: AA(int n=0):a(n) ; class BB:public AApublic: BB(int n)_ ; 其中横线处缺失部分是( )。(分数:2.00)A.:a(n)B.:AA(n)C.a(n);D.a=n;26.有如下程序: #includeiostream using namespace std; class Basel public: Basel(int d)
19、 coutd; Base1() ; class Base2 public: Base2(int d) coutd; Base2() ;class Derived:public Base1,Base2 public: Derived(int a,int b,int c,int d); Base1(b),Base2(a),b1(d),b2(c) Private: int b1; int b2; ; int main() Derived d(1,2,3,4); return 0: 运行时的输出结果是( )。(分数:2.00)A.1234B.2134C.12D.21国家二级 C+机试(继承和派生)模拟
20、试卷 13答案解析(总分:52.00,做题时间:90 分钟)一、选择题(总题数:26,分数:52.00)1.建立一个有成员对象的派生类对象时,各构造函数体的执行次序为( )。(分数:2.00)A.派生类、成员对象类、基类B.成员对象类、基类、派生类C.基类、成员对象类、派生类 D.基类、派生类、成员对象类解析:解析:建立派生类对象的时候,构造函数的执行顺序如下:执行基类的构造函数,调用的顺序按照基类被继承时候的顺序(自左向右)。然后是执行成员对象的构造函数,调用顺序按照各个成员对象在类中的声明顺序(自上而下),最后是执行派生类的构造函数。2.有如下类定义和变量定义: class Parents
21、 public: int publicData; private: int privateData; ; class ChildA:public Parents*类体略*; class ChildB:private Parents*类体略*; ChildA a; ChildB b; 下列语句中正确的是( )。(分数:2.00)A.coutapublicDataendl; B.coutaprivateDataendl;C.coutbpublicDataendl;D.coutbprivateDataendl;解析:解析:基类 Parents的私有成员 privateData在派生类 ChildA和
22、 ChildB中是不可以访问,所以选项 B、D 是错误,而派生类 ChildB私有继承基类 Parents,所以基类:Parents 的公有成员 publicData在派生类 ChildB中变为私有成员,只能在派生类 ChildB内部访问,因而选项 c是错误的。派生类 ChildA公有继承基类 Parents,所以基类 Parents的公有成员 publicData在派生类 ChildA中可以访问。3.通过派生类的对象可直接访问其( )。(分数:2.00)A.公有继承基类的公有成员 B.公有继承基类的私有成员C.私有继承基类的公有成员D.私有继承基类的私有成员解析:解析:基类的私有成员在派生类
23、中都是不能访问的,所以选项 B、D 是错误的,基类的公有成员通过私有继承后,在派生类中变为了私有成员,只能在派生类中进行访问,而通过派生类的对象不能访问,所以选项 C也是错误的。基类的公有成员通过公有继承后,在派生类中是公有成员,所以可以通过派生对象来访问。4.有如下程序: #includeiostream using namespace std; class AA int k; protected: int n; void setK(int k)this-k=k; public: void setN(int n)this-n=n; ; class BB:public AA*类体略*; int
24、 main() BB x; xn=1;1 xsetN(2); 2 xk=3; 3 x.setK(4); 4 return 0; 在标注号码的四条语句中正确的是( )。(分数:2.00)A.1B.2 C.3D.4解析:解析:因为类 BB公有继承自类 AA,所以 AA中的保护成员和公有成员在类 BB中仍是保护成员和公有成员。在选项 B中调用了公有成员函数 setN(int n)this-n=n;,对保护成员 n进行赋值操作。5.有如下两个类定义 class xx private: double x1; protected: double:x2; public: double x3; ; class
25、 YY:protected XX private: double y1; potected: double y2; public: double y3; ; 在类 YY中保护成员变量的个数是( )。(分数:2.00)A.1B.2C.3 D.4解析:解析:在 C+中派生类从基类保护继承时,基类的公有成员在派生类中改变为保护成员,基类的保护成员在派生类中仍为保护成员。所以对于本题来说,YY 类保护继承自类 XX,那么类 XX中的公有成员x3和保护成员 x2在派生类中都成为保护成员,再加上类 YY中的保护成员 y2,因此在派生类 YY中保护成员的个数为 3。6.有如下程序: #includeiost
26、ream using namespace std; class Music public: void setTitle(char*str)strcpy(title,str); protected: char type10; private: char title20; class Jazz:public Music public: void set(char*str) strcpy(type,Jazz); strcpy(title,str); ; 下列叙述中正确的是( )。(分数:2.00)A.程序编译正确B.程序编译时语句出错C.程序编译时语句出错 D.程序编译时语句和都出错解析:解析:派生
27、类 Jazz不能访问基类 Music中的私有成员 title。7.当派生类从一个基类保护继承时,基类中的一些成员在派生类中成为保护成员,这些成员在基类中原有的访问属性是( )。(分数:2.00)A.任何B.公有或保护 C.保护或私有D.私有解析:解析:基类的公有成员和保护成员只有在以保护继承方式继承时,其在继承类中是保护成员。8.下列关于派生类和基类的描述中,正确的是( )。(分数:2.00)A.派生类成员函数只能访问基类的公有成员B.派生类成员函数只能访问基类的公有和保护成员 C.派生类成员函数可以访问基类的所有成员D.派生类对基类的默认继承方式是公有继承解析:解析:派生类不论是采用那种继承
28、方式继承基类,它的成员函数只能访问基类的公有成员和保护成员。9.有如下类定义: class B public:void fun1() private:void fun2() protected:void fun3() ; class D:public B protected:void fun4() ; 若 obj是类 D的对象,则下列语句中不违反访问控制权限的是( )。(分数:2.00)A.pbj.fun1(); B.objfun2();C.objfun3();D.objfun4();解析:解析:派生类 D公有继承父类 B,所以 obj可以访问基类 B的公有,不能访问其它成员。10.有如下程序
29、: class Base public: int data; ; class Derivedl:public Base f; ; class Derived2:protected Base; int main() Derivedl d1; Derived2 d2; d1data=0; d2data=0; return 0; 下列关于程序编译结果的描述中,正确的是( )。(分数:2.00)A.皆无编译错误B.有编泽错误,无编译错误C.无编译错误,有编译错误 D.皆有编译错误解析:解析:保护继承的类 Dervied2不能访问基类 Base中的公共数据成员 data。11.有如下程序: #inclu
30、deiostream using namespace std; class xx int x; public: XX(int xx=0):x(xx) int getX()return x; ; class YY:public xx int y; public: YY(int xx,int yy):XX(xx),y(yy) int getV()return getX()+y; ; int main() YY c(3,4); coutcgetV()+cgetX()endl; return 0; 运行这个程序的输出结果是( )。(分数:2.00)A.3B.4C.7D.10 解析:解析:由于类 YY公
31、开继承自类 XX,所以执行表达式 cgetV()+cgetX()的值等于 3+3+4=10。12.有如下程序: #includeiostream using namespace std; class Media public: void Name();void Show(); protected: int page; ; class Book:private Mediapublic: void Print() coutpageendl; void Show()Media:Show(); ; int main() Book Bible; BibleName(); Bible.Print(); B
32、ible:Show(); return 0; 编译时有错误的是( )。(分数:2.00)A.语句B.语句 C.语句D.语句解析:解析:类 Book私有继承自类 Media,所以类 Media中的公有成员函数 Name()在继承类 Book中变成了私有成员函数,因而类 Book的对象 Bible不能访问私有成员函数 Name()。13.有如下程序: #includeiostream using namespace std; class A public: A()coutA; ; classBpublic:B()coutB; classC:public A B b; public: C()cout
33、C; ; int main()C obj;return 0; 执行后的输出结果是( )。(分数:2.00)A.CBAB.BACC.ACBD.ABC 解析:解析:此题考查的是类的继承和派生。系统首先要通过派生类的构造函数调用基类的构造函数,对基类成员初始化;然后对派生类中的新增成员初始化。14.有如下程序: #includeiostream using namespace std; class A public: A()coutA; A()coutA; ; class B:public A A*p; public: B()coutB;p=new A(); B()coutBt;delete p;
34、; int main() B obj; return 0; 执行这个程序的输出结果是( )。(分数:2.00)A.BAAABAB.ABABAA C.BAABAAD.ABAABA解析:解析:此题考查的是派生类对象的构造与析构。建立派生类对象时,构造函数的执行顺序如下:执行基类的构造函数,调用顺序按照各个基类被定义时声明的顺序(自左向右)-执行成员对象的构造函数,调用顺序按照各个成员对象在类中声明的顺序-执行派生类的构造函数。所以本题在建立派生类 B的对象 obj是会先调用基类 A的构造函数,然后调用自身的构造函数。注意:B 类中定义的成员 p是 A类的指针而不是一个对象,故在调用自身构造函数前不
35、需要构造。而在 B类构造函数中使用 new操作符动态地构造了一个 A类的对象,所以整个构造结果是输出:ABA。 派生类对象的析构与构造严格相反,即先析构自身,然后析构自身所包含的成员对象,最后调用基类的析构函数。故本题中当 main()函数返回时,析构B类的对象 obj:首先调用B(),接着再调用A()因为在B()函数中释放了动态创建的 A类对象,故整个析构所输出的结果是BAA。所以这个程序输出结果为 ABABA。15.有如下程序 #includeiostream using namespace std; class Base protected: Base()coutA; Base(char
36、 c)coutc; ; class Derived:public Base public: Derived(char c)coutc; ; int main() Derived dl(B); return 0; 执行这个程序屏幕上将显示输出( )。(分数:2.00)A.BB.BAC.AB D.BB解析:解析:此题考查的是派生类对象的构造。建立派生类对象时,构造函数的执行顺序是:执行基类的构造函数,调用顺序按照各个基类被被继承时声明的顺序:执行成员对象的构造函数,调用顺序按照各个成员对象在类中声明的顺序;执行派生类的构造函数。此题中,在建立派生类 Derived的对象 dl时会先调用基类 Bas
37、e的构造,调用的是默认构造函数,输出字符A;然后调用自身的构造函数,输出B;故程序的输出结果是:AB。16.在一个派生类对象结束其生命周期时( )。(分数:2.00)A.先调用派生类的析构函数后调用基类的析构函数 B.先调用基类的析构函数后调用派生类的析构函数C.如果基类没有定义析构函数,则只调用派生类的析构函数D.如果派生类没有定义析构函数,则只调用基类的析构函数解析:解析:此题考查的是派生类对象的析构。释放派生类对象时,析构函数的执行顺序是:首先调用派生类自身的析构函数;然后调用类成员对象的析构函数;最后调用基类的析构函数。所以四个选项中只有选项 A正确。17.下列关于派生类构造函数和析构
38、函数的说法中,错误的是( )。(分数:2.00)A.派生类的构造函数会隐含调用基类的构造函数B.如果基类中没有缺省构造函数,那么派生类必须定义构造函数C.在建立派生类对象时,先调用基类的构造函数,再调用派生类的构造函数D.在销毁派生类对象时,先调用基类的析构函数,再调用派生类的析构函数 解析:解析:此题考查的是派生类的构造函数和析构函数。在撤销派生类对象时,析构函数的执行过程和构造函数严格相反,即:对派生类新增普通成员进行清理;调用成员对象析构函数,调用基类析构函数对基类进行清理。18.下列有关继承和派生的叙述中,正确的是( )。(分数:2.00)A.派生类不能访问基类的保护成员B.作为虚基类
39、的类不能被实例化C.派生类应当向基类的构造函数传递参数 D.虚函数必须在派生类中重新实现解析:解析:此题考查的是继承和派生。无论使用哪种继承方式,派生类中的成员都不能访问基类中的私有成员,而可以访问基类中的公有成员和保护成员,所以选项 A错误;C+中只有抽象类不能被实例化,而虚基类不一定非得是抽象类。所以选项 B错误;在派生类中可以重新定义从基类继承下来的虚函数,也可以不重新定义,故选项 D错误。19.有如下程序: #includeiostream using namespace std; class A public: A(int i)x=i; void dispa,()coutx,; pr
40、ivate: int x; ; class B:public A public: B(int i):A(i+10)x=i; void dispb()dispa();coutxendl;private int x: ; int main() B b(2); bdispb(); return 0; 运行时输出的结果是( )。(分数:2.00)A.10,2B.12,10C.12,2 D.2,2解析:解析:此题考查的是派生类的构造。主函数中,首先声明 B类的对象 b,执行进入 B的构造函数B(int i)再接着执行 A的构造函数 A(int i),形参 i为 12,x 被赋值 12;通过对象 b调用其
41、成员函数dispb(),输出结果 12:接着执行函数 dispb()的第 2条语句输出 2,然后主函数结束。20.有如下程序: #includeiostream using namespace std; class Base int x; public; Baseint n=0;x(n)coutn; Int getX()constreturn x; ; class Derived public Base int y; public; Derived(int m,int n):y(rn),Base(n)coutm; Derived(int m):y(m)coutm; ; int main() D
42、erived dl(3),d2(5,7); return 0; 运行时的输出结果是( )。(分数:2.00)A.375B.357C.0375 D.0357解析:解析:此题考查的是派生类的构造与析构。建立派生类的对象时,构造函数的执行顺序如下:执行基类的构造函数,调用顺序按照各个基类被继承时声明的顺序(自左向右)-执行成员对象的构造函数,调用顺序按照各个成员对象在类中声明的顺序-执行自身的构造函数。此题中,执行语句 Derived d1(3)首先调用基类的构造函数,输出 0;接着调用自身的构造函数输出 3。执行语句 Derived d2(5,7)时,会调用基类的 Base(n)函数输出 7;然后
43、执行继承类中的 Derived(int m,int n)的 y(m)输出 5。21.有如下程序: #includeiostream using namespace std; class AA public: AA()cout1; ; class BB:public AA int k: public: BB():k(0)cout2; BB(int n):k(n)cout3; ; int main() BB b(4),c; return 0; 运行时的输出结果是( )。(分数:2.00)A.1312 B.132C.32D.1412解析:解析:在基类 AA的默认构造函数中,输出字符1,在继承类 BB
44、的默认构造函数中,输出字符2,在带有参数 n的构造函数中,输出字符3。在主函数中,在创建 BB的对象 b(4)时,会首先调用基类 AA的构造函数输出字符1,再调用类 BB带参数的构造函数输出字符3。在创建 BB的对象c时,会首先调用基类 AA的构造函数输出字符1,再调用类 BB默认的构造函数输出字符2。所以程序输出的结果为 1312。22.有如下程序: #includeiostream using namespace std; class C1 public: C1()cout1; ; class C2:public C1 public: C2()cout2; ; int main() C2
45、cb2; C1*cb1; return 0; 运行时的输出结果是( )。(分数:2.00)A.121B.21 C.211D.12解析:解析:在主函数中定义 C2类的对象,当程序结束时,首先调用 C2类的析构函数C2,输出 2,再调用 Cl类的析构函数C1,输出 1。所以程序运行的结果就是 21。23.有如下程序: #includeiostream using namespace std; class Base public: Base(int x=0):valB(x)coutvalB; Base()coutvalB; private: int valB; ; class Derived:pub
46、lic Base public: Derived(int x=0,int y=0):Base(x),valD(y)coutvalD; Derived()coutvalD; private: int valD; ; int main() Derived obj 12(2,3); return 0; 运行时的输出结果是( )。(分数:2.00)A.2332 B.2323C.3232D.3223解析:解析:在主函数中创建类 Derived对象 obj12(2,3)时,因为类 Derived是从基类 Base派生而来,所以首先调用基类的构造函数;输出 2,再调用派生类构造函数,输出 3。当主函数运算结果时,首先调用派生类的析构函数,输出 3,再调用基类的析构函数输出 2。所以输出结果为 2332。24.生成派生类对象时,派生类构造函数调用基类构造函数的条件是( )。(分数:2.00)A.无需任何条件 B.基类中显示定义了构造函数C.派生类中显式定义了构造函数D.派生类构造函数明确调用了基类构造函数解析:解析:因为派生类从基类中继承,它含有基类中的数据成员和函数成员,所以当生成派生类