您好,欢迎来到划驼旅游。
搜索
您的当前位置:首页C++程序设计模拟试题

C++程序设计模拟试题

来源:划驼旅游
自考面向对象C++程序设计模拟试题

一、单项选择题(本大题共10小题,共20分) 在每小题列出的四个选项中,只有一个是符合题目要求的,请将其代码填在题后的括号内。错选或未选均无分。

1.面向对象程序设计中的数据隐藏指的是 参为:D A.输入数据必须输入保密口令 B.数据经过加密处理

C. 对象内部数据结构上建有防火墙 D.对象内部数据结构的不可访问性

[解析]输入数据必须输入保密口令和数据经过加密处理都不是面向对象程序设计的特征;对象内部数据结构上也不可能建有防火墙,所以它们都不是面向对象程序设计中所指的数据隐藏。面向对象程序设计系统中的封装单位是对象,对象之间只能通过接口进行信息交流,外部不能对对象中的数据随意地进行访问,这就造成了对象内部数据结构的不可访问性,也使得数据被隐藏在对象中。这就是面向对象程序设计中的数据隐藏所指。 2.下列各项中不符合函数重载必须满足的条件的是 参为:D A. 必须有不同的参数个数 B.对应的参数类型必须不相同 C. A和B必须同时满足

D.A和B只要满足一个即可

[解析]我们知道,在同一个作用域中,要实现函数重载必须满足的条件的是:① 有不同的参数个数;或者 ② 对应的参数有不相同的数据类型,即①和②中只要有一个满足就可以了。当然两者都满足更好,但这不是必须的。

3.下列带缺省值参数的函数说明中,正确的说明是 参为:A A.int Fun(int x,int y=2,int z=3); B.int Fun(int x=1,int y,int z=3); C. int Fun(int x,int y=2,int z); D.int Fun(int x=1,int y,int z=3);

[解析]在带缺省值参数的函数说明中,正确的说明应该是无缺省值的参数依次排列在参数表的左边,排完无缺省值的参数后,再依次排列带缺省值的参数。从所给出的四个选项来看,只有“int Fun(int x,int y=2,int z=3)”符合这条规定,其它的都不符合。 4.有如下的对类“CSample”的说明,其中( )是错误的。 class CSample { 参为:A A.int a=23; B.CSample(); public:

C.CSample(int val); D.~ CSample(); }

[解析]在下面对类“CSample”说明中,“CSample()”和“CSample(int val)”是该类重载的构造函数、“~ CSample()”是该类的析构函数,这三个语句都是正确的。错误的语句是“int a=23”,因为它违反了在类的声明(不管是引用性声明,还是定义性声明)中都不能以赋值表达式的形式给它的数据成员进行初始化。

5.已知类A中的一个成员函数的说明如下:

void Set(A &a);

则该函数的参数“A &a”的含义是 参为:C A.指向A的指针为a

B.将变量a的地址赋给类A

C.类A对象引用a用作函数的形参 D.变量A与a按位与后作函数参数 [解析]因为A是一个类,所以“A &a”表示a是类A的对象,但因为对象a的前缀了符号“&”,则“&a”表示是类A的对象引用。所以“A &a”的含义是类A对象引用a用作函数的形参。 6.若类A和类B的定义如下: class A { public: int i,j; void get(); };

class B:A { int i,j; protected:

int k; public:

void make(); };

void B::make() { k=i*j; }

则其中()是非法的表达式。 参为:D A.void get(); B.int k;

C.void make(); D.k=i*j;

[解析]对于给定的四项中,前三项都是正确的,只有第四项是错误的。因为,类B是类A的私有派生类(缺省访问类型),所以A中的公类型的数据成员在类B中成为了私有数据成员,但函数“void B::make()”既然是类B的成员函数,则既可访问类A中的公有数据成员,也能访问类B中的私有数据成员,则表达式“k=i*j;”造成了访问的二义性,即其中的i和j,到底是取自类A呢?还是取自类B呢?

7.下面的主程序中,语句( )是错误的。 class A { int i; public:

virtual void fun()=0; A(int a) { i=a; } };

class B { int j; public:

void fun() , cout<<”B::fun()\\n”; - B(int b,int c) :A(b) { j=c; }

};

void main() 参为:A A.{ A a(5); B.A *pa; C.B b(7); D.B *pb; }

[解析]在类A中,函数“virtual void fun()=0”为纯虚函数,因此,类A为抽象类。作为抽象类,它是不能被用来定义具体对象的,而语句“A a(5);”恰恰是定义抽象类的对象的,所以它是错误的

8.拷贝(复制)构造函数的作用是 参为:C A.进行数据类型的转换 B.用对象调用成员函数 C.用对象初始化对象

D.用一般类型的数据初始化对象

[解析]进行数据类型的转换和用一般类型的数据初始化对象都是一般构造函数的功能。用对象调用成员函数不用构造函数,只要用“对象名.成员函数名”即可。所以拷贝(复制)构造函数的作用,只能是用对象来初始化对象。

9.下列说法中,正确的说法是 参为:B A.所有的运算符都能被重载

B.运算符被重载时,它们的优先级与结合性不会改变 C.当需要时,我们可以自定义一个运算符来进行重载 D.每个运算符都可以被重载成成员函数和友元函数 [解析]当重载运算符时,不是所有的运算符都能被重载,有几个运算符是不能被重载的,如三元运算符“?:”、‘.’、‘*’、‘::’、‘#’等;也不是每个运算符都可以被重载成成员函数和友元函数,如运算符‘=’、‘()’、‘*+’、和‘→’都只能被重载成成员函数;无论何时,都不能自定义运算符来进行重载,也即重载只能对已有运算符进行;但是运算符被重载时,它们的优先级与结合性不会改变。

10.下面对结构或类中成员的访问中,不正确的访问是 参为:A A.*pointer.salary; (其中pointer为指向类对象的指针) B.pointer->salary;

C.x=worker.salary; (其中worker为具有类类型的对象)

D.Location &rA=A1;int x=rA.GetX(); (Location为已定义的类,A为对象)

[解析]因pointer为指向类对象的指针,所以“pointer->salary”是正确的访问数据成员的形式;因worker为具有类类型的对象,所以“worker.salary”也是正确的访问数据成员的形式;因Location为已定义的类,A1为对象,所以“Location &rA=A1;int x=rA.GetX();”表示以对象A1初始化对象引用rA,然后由对象引用rA调用成员函数GetX()给变量x赋值,这样的访问成员函数的形式也是正确的;“*pointer.salary;”中,因为运算符‘.’的优先级高于运算符‘*’的优先级,所以相当于“*(pointer.salary);”,那正确的形式应该是“*(pointer→salary);”。故“*pointer.salary”是不正确的访问。

二,填空题(本大题共10小题,共20分)

不写解答过程,将正确的答案写在每小题的空格内。错填或不填均无分。 11.面向对象程序设计中的多态性包括静态多态性和动态多态性,前者由____________机制支持,而后者则由____________机制支持。

答:函数重载、虚函数

[解析]静态多态性又称编译时多态性,调用何函数应该在编译之前就知道了,所以必须由函数重载机制来支持。动态多态性又称运行时多态性,调用何函数只有在运行时才知道,所以由虚函数(与指针或引用)机制来支持。

12.由char const *str=”stucture”;所以定义的指针称为____________,关键字const 所修饰的是____________。

答:指向常量的指针、指针所指的字符串

[解析]根据由‘*’在修饰符“const”中位置的不同,它所修饰的对象也不同,“const ”表示所修饰的是指针所指的常量,该指针称为指向常量的指针;“* const”表示所修饰的是指针本身,该指针称为常指针;“* const *”则表示所修饰的是指针本身和指针所指常量,该指针称为指向常量的常指针。

13.引入虚基类的目的是为了解决多重继承中的____________和____________问题。 答:二义性、多占用空间

[解析]在允许多重继承时可能出现两个问题,第一个是公有派生类中的成员通过不同基类调用它们上一级公共基类的同一成员,这就产生了调用的二义性;每一个基类都为它们的上一级公共基类存有备份,这就引起了公共基类的重复存储,也就多占了存储空间。引入虚基类的目的是为了解决多重继承中的这两个问题。 14.派生类中所定义的虚函数的____________不影响对它的动态联编,即基类中已定义的虚函数,其同名函数放在派生类中的__________,都可以实现运行时多态性。 答:访问属性、任何地方

[解析]对虚函数的能否在类外调用,取决于基类中定义它时是否具有公的访问属性,而派生类中重新定义的虚函数的访问属性不影响它的特性,即对它的动态联编。也即基类中已定义的虚函数,其同名函数放在派生类中的任何地方,都可以实现运行时多态性。 15.构造函数与析构函数所调用的虚函数是____________的函数,因此调用时实现的是____________联编。

答:所在类、静态

[解析]在生成派生类的对象时,先调用基类的构造函数生成基类对象,再调用派生类的构造函数来生成派生类对象。所以当在构造函数中调用虚函数时,当调用基类的构造函数时,此时派生类还未生成,所以它只能调用自己的虚函数;调用派生类构造函数时,它也只能调用自己的虚函数,因为虚函数的调用是不能由派生类调用基类的。在析构派生类对象是时,先调用派生类的析构函数析构掉派生类对象,再调用基类的析构函数来析够掉基类的对象。所以当在析够构函数中调用虚函数时,派生类的析构函数调用的是它自己的虚函数(原因同构造函数),基类的析构函数调用的也是它自己的虚函数,因为此时派生类对象以已被析构掉了。由上可见,当构造函数与析够函数调用虚函数时,它们调用的都是自己类的函数,因此调用时实现的是静态联编。

16.C++的____________规则能保证编译器调用正确的成员函数。有时为更保险地保证编译器调用正确的成员函数,可以使用____________操作符。 答:作用域、作用域分辨符

[解析]C++的作用域规则能隐式地保证编译器调用正确的成员函数。为清楚地显式地保证编译器调用正确的成员函数,可以使用作用域分辨操作符::,使用“类名::成员函数”来说明该成员函数属于哪个类。 17.说明一个const成员函数(又称常量成员函数)的方法是,将const写在__________之间,而且它修饰的是__________。

答:函数头与函数体、this指针

[解析]为了说明一个常量成员函数的方法是,将const写在函数头的右圆括号‘)’与函数体的左花括号‘,’之间,而且它修饰的是对象所属的this指针。表示该函数不能修改它所在对象中的数据成员的值。

18.除析构函数外,不能带有参数的函数还有____________,而且它的返回数据类型不能随便指定,而由____________来决定。

答:类型转换函数、return语句中返回变量的类型

[解析]除析构函数外,不能带有参数的函数还有类型转换函数,类型转换函数的返回数据类型是不能随便指定的,必须由return语句中返回变量的类型来决定。

19.当使用new动态生成一个对象时,隐含着对____________的一次调用;而当使用delete删除一个对象时,隐含着对____________的一次调用。 答:构造函数、析构函数

[解析]当使用new动态生成一个对象时,隐含着对构造函数的一次调用,用来生成对象;而当使用delete删除一个对象时,隐含着对析构函数的一次调用,以析构需删除的对象。 20.对某个运算符的重载,实际上是用关键字____________与该运算符组成一个运算符函数,而且该运算符函数的返回类型不能是____________的。 答:operater、void [解析]对某个运算符的重载,实际上是用关键字operater 与该运算符组成一个运算符函数,而且该运算符函数的返回类型不能是无类型的,即不能是void的。 三,改错题(本大题共5小题,每小题2分,共10分) 21.分析下列程序中的错误,并说明出错原因。 # include class base { const int n; public:

base() , cout<<”Initializing default\\n”; - base(int m) , cout<<”Initializing\\n”; n=m; - ~base() , cout<<”Destroying\\n”; - };

void main() { base x=1; base y=x; }

答:(1) n=m; const数据成员不以该形式赋值 (2)错误处base y=x;,以对象初始化对象

[解析](1)作为const数据成员n不能用赋值表达式的形式为其赋初值,必须在定义构造函数时在函数头中以“base(int m):n(m)”形式来初始化。

(2)base y=x; 语句中‘=’不是赋值的意思,而是初始化的意思。即在定义类base的对象y时,以对象x给它初始化,相当于base y(x);。但是以对象初始化对象时,必须调用拷贝构造函数才行。因程序中没给出拷贝构造函数,也不能调用系统的缺省拷贝构造函数,因用户给出了构造函数后,再也不能调用系统提供的任何缺省构造函数。所以,base y=x;是错误的。

22.分析下列程序中的错误,并说明出错原因。 #include class AA {

public: int aa; };

class BB:virtual public AA { int bb; };

class CC:virtual public AA { public: int bb; };

class DD:public BB,public CC { public: float dd; };

void main() { DD p; int m=p.aa; AA *pr=&p; AA &pt=p;

DD *pp=(DD *)(BB *)pr; AA r;

DD &ps=r; }

答:(1)DD *pp=(DD *)(BB *)pr;,虚基类指针不能赋给派生类指针 (2)DD &ps=r;,虚基类对象不能初始化派生类对象引用

[解析]赋值兼容规则的三条规则是:公有派生的情况下,派生类的对象可以赋给基类的对象;派生类的对象可以初始化基类对象的引用;派生类对象地址可以赋给指向基类对象的指针。反过来,以上三条规则是错误的。

(1)将虚基类AA的指针pr赋给派生类DD的指针pp,这违背了赋值兼容规则。 (2)虚基类AA的对象r初始化派生类DD的引用ps,这违背了赋值兼容规则。 23.分析下列程序中的错误,并说明出错原因。 #include class A { int x; public:

A(int a) { x=a; fun(); }virtual void fun()=0; };

class B:public A { public:

B(int b) :A(b) {} void fun() { } };

void main() { A aa(5); B bb(8); }

答:(1)fun();,构造函数不能调用纯虚函数

(2)A aa(5); 抽象类不能定义对象

[解析](1)在构造函数“A(int a)”调用了纯虚函数“fun()”,因构造函数调用虚函数是静态联编,即调用的是它自己类的虚函数。在此调用的是纯虚函数,它只被说明,而未定义,所以不可能被执行,因此出错。

(2)抽象类相当于是对类的引用性声明,所以它只能定义该类的指针和引用,而不能定义它的对象。在此,A为抽象类,而“A aa(5)”却定义了A的对象,因此是错误的。 24.分析下列程序中的错误,并说明出错原因。 #include void fun()

, ifstream myfile(“d:\\abcd”); myfile<<”my file\\n”; }

void main() { fun(); }

答:(1)ifstream ,输出必须用输出流ofstream (2)myfile(“d:\\abcd”);,必须用‘\\’

[解析](1)由函数“fun()”的函数体可见,它要输出信息“my file”,为此必须让文件与输出流相关联,但“ifstream”是输入流,与之关联的文件只能输入信息。所以,必须使用输出流“ofstream”。

(2)作为文件面的“d:\\abcd”是字符串,其中字符‘\\’一般作为转义符使用。为了在字符串中使用该字符的原义必须用双字符,即“\\”。 25.分析下列程序中的错误,并说明出错原因。 #include class AA { int aa;

AA(int xx) { aa=xx; } public:

int get() { return aa; }

~AA() , cout<<”Destroying”< };

main()

{ AA elem[3]={5,8,4};

for (*int i=0;i<3;i++) cout< }

答:(1)AA(int xx) 的访问属性错、应具有公有属性 (2)数组elem[3]初始化错、因调用构造函数

[解析](1)构造函数虽是由系统自动调用来生成对象的,但一般都是在类外调用,所以它的访问属性必须是公有的。程序中构造函数的访问属性是私有的(缺省值),运行中必定出错。

(2)对于数组元素的初始化,当程序中提供了带参构造函数时,一般不能直接用数值表的形式来实现(如程序中所示),对只含有一个参数的构造函数,初始化数组的实现方式如下所示:AA elem[3]={ AA(5),AA(8),AA(4)};

四,完成程序题(本大题共5小题,每小题4分,共20分) 根据题目要求,完成程序填空。

26.仔细阅读下列求两个点之间距离的程序,根据程序的输出结果在划线处填入正确语句。

#include #include class point { float x,y; public:

point(float a,float b) { x=a; y=b; } float distance(point &p) {

float dx=_____①______; float dy=_____②______;

return (float)srrt(da*da+dy*dy); } };

void main()

{ point p1(2,3),p2(32,43); cout<<_____③_____< }

输出结果:50 答:① p.x-x ② p.y-y

③ distance(p2)

[解析]由于求两点之间距离的函数“distance”为成员函数,所以由该函数的this指针所指对象可用作起点(参数之一),另一个用作终点的参数,必须在函数的参数表中显式地给出。dx 和dy分别计算两个结点间x和y坐标间的距离,因此应该为:dx=p.x – x 和 dy =p.y – y。对它们求平方相加后开方即可,得到两点间的距离:(float)srrt(da*da+dy*dy)。在主程序中求p1和p2两个结点之间的距离,由于由p1调用距离函数,所以由p2作为它的参数,即distance(p2)。

27.完成如下的程序,使得输出为: base::10 base::12 derived::24 #include class base { int x; public:

base(int a) { x=a; }

_________①__________; };

class derived:public base { int y; public:

derived(int a,int b):base(a) { y=b; } _________②_________; };

void main() { base b(10),*p; derived d(12,24); b.print(); p=&d; p->print(); }

答:① virtual void print() , cout<<”base::”< ② viod print() , base::print(); cout<<”derived::”<

[解析]从主程序可见,“b.print();”是由基类的对象调用它的成员函数,要输出的是“base::10”,意味着基类中必须定义一个成员函数“print()”,该函数手它必须有输出语句“cout<<”base::”public: virtual void fun()=0; };

class Menu1:public Menu {

public: void fun() , cout<<”do something for Menu1 !\\n”; - };

class Menu2:public Menu {

public: void fun() , cout<<”do something for Menu2 !\\n”; - };

class Menu3:public Menu {

public: void fun() , cout<<”do something for Menu3 !\\n”; - };

void main() { Menu *pm[3]; pm[0]= new Menu1; pm[1]=new Menu2; pm[2]=new Menu3; int num; do {

cout<<;”1—Menu1 \\n”;

cout<<”2—Menu2 \\n”; cout<<”3—Menu3 \\n”;

cout<<”enter your choose !\\n”; cin>>num;

if(______①______) _______②_______fun(); } while(_____③_____); }

答:① num>=1&&num<=3 ② pm[num-1]. ③ num!=0

[解析]这个程序要完成的是菜单功能。在基类中定义了一个纯虚函数“fun()”,在下面的三个派生类中,各自分别对函数“fun()”进行了重新定义,以便完成各自的功能。因为只有三个菜单项,所以只在num取值范围在1和3之间时,才能执行所需功能,故在①处填入“num>=1&&num<=3”。当num取值范围在1和3之间时,分别执行菜单Menu1~Menu3的功能,也即执行派生类中相应函数“fun()”,为此要由指向各个派生类对象的基类指针来完成。由主程序可见,基类指针数组的各元素分别被赋给了各派生类的对象地址,考虑到C++数组的下标从0开始,②处填入“pm[num-1].”是正确的。为了使菜单循环工作,只有当输入0时才退出循环,③处应填入“num!=0”。

29.两个复数只有当它们的实部和虚部分别相等时,才被认为它们相等。在空格处填入合适的内容,以完成下面的程序,使其重载运算符“==”,用以比较两个复数的相等。请在主函数中输出比较的结果。 #include

class complex { double real,imag; public:

complex(double r,double i) { real=r; imag=i; } bool operator==(complex &); };

int complex:: operator==(complex &com) { return(_____①_____) } void main()

{ complex c1(12.3,32.5),c2(21.7,18.6); if(______②______)

return cout<<”true\\n”; else

return cout<<”false\\n”; }

答:① (real==com.real)&&(imag==com.imag) ② c1==c2或c1.operator==(c2) [解析]若两个复数的相等,则必有它们的实数部分和虚数部分都相等,所以运算符重载函数中返回“(real==com.real)&&(imag==com.imag)”,只有real==com.real与imag==com.imag都为真时,该函数的返回值才为真。在主程序中,为了比较两个复数c1和c2,可以隐式地写成“c1==c2”,也可显式写成“c1.operator==(c2)”。

30.下列程序中声明了两个类AA和BB,其中函数“print”是类AA的成员函数,但是类BB的友元函数。请在①、②和③处各填入正确的内容,使程序能正常运行。

#include

_____①______; class AA {

int t; public:

AA(int x) { t=x; } void print(BB &b); };

class BB { int s; public:

BB(int y) { s=y; }

friend void ___②___print(BB &); };

void ____③_____

{ cout<<”AA:”< void main() { AA m(6); BB n(8); m.print(n); }

输出结果为:AA:6;BB:8 答:① class BB; ② AA::

③ AA::print(BB &w)

[解析]由于AA类的成员函数“print”是类BB的友元函数,因此它必须有一个BB类的引用作为参数,以便有引用BB类数据成员的接口。但此时BB类还未定义,为解决此矛盾,在①处先对BB类作引用性声明“class BB;”,告诉系统BB类在后面定义。因为函数“print”是类AA的成员函数,在类外定义必须加上类名和作用域分辨符,即在②处加上“AA::”。在BB类外定义“print”时,因是友元,所以没有加上“BB::”的必要,但“AA::”还是必须加的,所以在③处填“AA::print(BB &w)”。

五,程序分析题(本大题共6小题,每小题5分,共30分) 给出下面各程序的执行结果。

31.请分析以下的程序,给出该程序的正确执行结果。 #include

int add(int x,int y) { return x+y; } void main()

{ int m=2,n=3;

cout<<”1:”< m=2,n=3;

cout<<”2:”< m=2,n=3;

cout<<”3:”< m=2,n=3;

cout<<”4:”< }

答:1:7 2:8 3:8 4:9

[解析]在说明答案之前,要说明两个问题:

(1)C++语言中,函数参数是压在栈里的,因压栈是从前往后进行的,所以出栈就是从后向前进行的,也即先取最后的参数,然后再向前逐个取用; (2)对于单加运算,m++是先执行后加1,++m是加1后再执行。 由此,因m=2,n=3;,所以:

1:(m++)+(m+n)=2+(2+3)=7 (m++后执行,且后加1,所以m=2一直未变)

2:(++m)+(m+n)=3+(2+3)=8 (++m后执行,但先加1,执行++m时,m=3了)

3:(m+n)+( m++)=(3+3)+2=8 (先执行m++,后加1,执行m+n时,m=3了)

4:(m+n)+(++m)=(3+3)+3=9; (先执行++m,且先加1,故一开始就有m=3)

32.请分析下面的程序并给出该程序的执行结果。 #include class AA { int a; public:

AA() { cout<<”Initualizing AA!\\n”; } ~AA() { cout<<”Destroying AA!\\n”; };

class BB { int b; AA p; public:

BB() { cout<<”Initualizing BB!\\n”; } ~BB() { cout<<”Destroying BB!\\n”; };

void main() { BB X;

cout<<”Ending main!\\n”; }

答:Initualizing AA! Initualizing BB! Ending main! Destroying BB! Destroying AA!

[解析]虽然在主程序中只定义了一个类BB的对象,但在类BB中声明了类AA的对象作为它的数据成员。当

一个类中含有对象作为数据成员时,在生成对象时,先调用成员对象的构造函数,再调用类自己的构造函数,所以输出了“Initualizing AA!”(成员对象构造函数的输出)和“Initualizing BB!”(类自己构造函数的输出)。对象生成后,执行下一句输出语句,则输出“Ending main!”。此时程序结束,调用析构函数来析构掉对象,先调用类自身的析构函数,其输出为“Destroying BB!”,再调用成员对象的析构函数,其输出为“Destroying AA!”。 33.写出下列程序的运行结果。 #include class AA { int a; public:

AA(int i) , a=i; cout<<”AA=”< virtual ~AA() , cout<<”~AA=”< };

class BB:public AA { int b; public:

BB(int i,int j):AA(i) , b=j; cout<<”BB=”< ~BB() , cout<<”~BB=”< };

void main()

{ AA *pa=new AA(8); delete pa;

AA *pb=new BB(6,9); delete pb; }

答:AA=8 ~AA=8 AA=6 BB=9 ~BB=9 ~AA=6

[解析]语句“AA *pa=new AA(8);”动态生成一个类AA的对象并把它的地址赋给对象指针“pa”,为此系统调用了AA的构造函数,输出AA=8。接下来,执行语句“delete pa;”删除该对象指针,其实是删除了动态生成的对象,因此调用类AA的析构函数,输出~AA=8。接着执行语句“AA *pb=new BB(6,9);”,动态生成一个类BB的对象,并将其地址赋给类AA的指针“pb”。在生成派生类BB对象时,系统首先调用基类AA的构造函数输出AA=6,然后调用派生类BB的构造函数输出BB=9。最后执行语句“delete pb;”,由于基类AA的析构函数被定义为虚函数,因此在运行时是动态联编的。故系统先调用派生类BB的析构函数输出~BB=9,再调用基类AA的析构函数输出~AA=6(若基类析构函数非虚函数,则只输出~AA=6)。 34.写出下列程序的运行结果。 #include class AA {

public: static int n; AA() { n++; } };

int AA::n=0; main()

, cout<<”AA::n=”< AA d1; cout< AA d2; cout< AA d3,d4; cout< cout< }

答:AA::n=0 d1.n=1 d2.n=2 d1.n=4 d2.n=4

[解析]由于数据成员n的访问属性是公有的,所以在类外可访问它;又它是静态变量,所以具有全局性。在构造函数中,执行的是n++操作,即每次调用构造函数n就加1。当程序开始时,因未定义对象,所以n的值为初始化时的值,则输出为“AA::n=0”。当定义了对象d1后,由于调用了构造函数,则该对象中n=1,故输出“d1.n=1”。同理,对象d2输出“d2.n=2”。由于接下来生成了两个对象d3和d4,调用两次构造函数,n两次加1,此时n=4,所以下面两条语句的输出为“d1.n=4”和“d2.n=4”。 35.写出下列程序的输出结果。 #include class AA { public:

AA,- , cout<<”Constructor of AA. \\n”; fun(); - virtual void fun() , cout<<”AA::fun() calle

D.\\n”; - };

class BB:public AA { public:

BB(), cout<<”Constructor of B B.\\n”; fun(); -

void fun() , cout<<”BB::fun() calle D.\\n”; - };

void main() { BB d; }

答:Constructor of AA.

AA::fun() called. Constructor of BB. BB::fun() called.

[解析]虽然函数fun()说明为虚函数,但当在构造函数中被调用时,呈现的是静态联编,即基类和派生类都调用各自的函数fun()。所以,当生成对象d时,先调用基类的构造函数,在构造函数中又调用自己的函数“fun()”,所以输出为“Constructor of AA.”和“AA::fun() called.”。同理调用派生类的构造函数时,生成的输出为“Constructor of BB.”和“BB::fun() called.”。 36.请给出下面的程序的输出结果。 #include template

void sort(T* a,int n) { T num; for(int i=0;i { for(int j=i;j if(a[j]>a[j+1])

{ num=a[j]; a[j]=a[j+1]; a[j+1]=num; } }

for(i=0;i cout< cout< }

void main()

{ int iver[5]={ 12,45,9,23,37 };

double dver[5]= { 22.3,56.7,43.5,13.8,8.6 }; sort(iver,5); sort(dver,.5); }

答:9 12 23 37 45 8.6 13.8 22.3 43.5 56.7

[解析]这是使用模板的例子。函数sort是一个递增的排序函数,T是个模板。当数组是整型数据类型时,它为整型数组排序;当数组为双精度数据类型时,它为双精度数组排序。所以输出如上结果。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo6.com 版权所有 湘ICP备2023023988号-11

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务