|
最初由 ltkun 发表
1 请回答,下面程序的执行结果为什么不是:
B: b=77
C: c=999
C: c=999
而是:
B: b=77
C: c=145
C: c=145
#include<iostream.h>
class A{ public:
virtual void show(int a=145){cout<<"A: a="<<a<<endl; }
};
class B:public A
{ public:
void show(int b){ cout<<"B: b="<<b<<endl; }
};
class C:public B
{ public:
void show(int c=999){ cout<<"C: c="<<c<<endl; }
};
class D:public C
{ public:
void show(){ cout<<"D:\n"; }
};
void main()
{ A a,*pa=&a;
B b; C c; D d;
pa=&b; pa->show(77);
pa=&c; pa->show();
pa=&d; pa->show();
} /*执行结果:B: b=77
C: c=145
C: c=145 */
2 下面程序的执行结果的最后一行为什么不是:base1: a=3 b=9? 而是base1: a=0 b=0?
#include<iostream.h>
class base1{ int a,b;
public:
base1(int aa=0,int bb=0) //构造函数
{ a=aa; b=bb;
cout<<"base1 class!"<<endl; }
void show(){ cout<<"base1: a="<<a<<" b="<<b<<endl; }
};
class base2{ public:
base2(){ cout<<"base2 class!"<<endl; }
void show2(){ cout<<"base2: "<<endl; }
};
class level1:public base2,virtual public base1
{ public:
level1(int a,int b):base1(a,b)
{ cout<<"level1 class!"<<endl; }
};
class level2:public base2,virtual public base1
{ public:
level2(int a,int b):base1(a,b)
{ cout<<"level2 class!"<<endl; }
};
class lastlevel:public level1,virtual public level2
{ public:
lastlevel(int a,int b):level1(a,b),level2(a,b)
{ cout<<"lastlevel class!"<<endl; }
};
void main()
{ lastlevel obj(3,9);
obj.show(); //直接调用间接基类base的公有成员函数show()
}/*执行结果:base1 class!
base2 class!
level2 class!
base2 class!
level1 class!
lastlevel class!
base1: a=0 b=0 */
二 简答题(每小题5分,共10分)
1 学校有关教学人员的信息可以分为“学生”和“教师”两大类,而学生(Student)和教师(Teacher)都属于“人”(People)类,可以从People类继承。学校中有在职博士生(Doctor_Teacher),他们既是教师,同时又是攻读博士学位的学生。因此,Doctor_Teacher类可以从Student和Teacher类继承。现有如下两种不同的继承方式(继承结构图分别为case1和case2),请描述这2种继承各有什么不同?
2 对于上面第1小题的4个类:People、Teacher、Student、Doctor_Teacher,如果让你把其中一个类定义成抽象类,你定义哪一个类?为什么?
三 选择题(每空1分,共10分)
1 编写程序时,尽可能做到 。
⑴ 程序的语句数越少越好 ⑵ 循环语句尽量不用
⑶ 提高程序的可读性 ⑷ 减少函数被调用的次数
⑵ 只要语句不多于10条的函数都可以定义成内联函数。
⑶ 语句少的构造函数最好定义成内联函数,可以提高效率。
⑷ 内联函数可以免去函数调用的开销。
⑸ 把那些调用不频繁的函数定义成内联函数可以提高程序运行效率。
2 一个数组所占有的内存空间是 的。
⑴ 连续 ⑵ 不连续 ⑶ 随机分配 ⑷ 小的数组是连续的、大的数组可以是不连续
3 用new创建的局部动态对象的作用域是 。
⑴ 局部作用域 ⑵ 函数作用域 ⑶ 文件作用域 ⑷ 函数原型作用域
4 如果Student类继承于People类,下面 说法是正确的。
⑴ Student 类包含了People类的全部成员。
⑵ Student类的对象包含了People的全部数据成员。
⑶ Student类的对象包含People的哪些成员,取决于继承类别。
⑷ 如果Student类私有继承了People类,则Student类的对象中就不包含People类的私有成员。
5 抽象类的构造函数不能定义成 的。
⑴ public ⑵ private ⑶ protected
6 把某一个类设计成抽象类的主要目的是 。
⑴ 拒绝用户定义对象。
⑵ 为众多派生类指定统一的公共接口,使得派生类不必再编写这些接口代码。
⑶ 使得在继承时不必考虑抽象父类的数据结构,因为抽象父类不能定义对象。
⑷ 为众多派生类指定统一的公共接口。
7 关于抽象类,下面 说法是正确的。
⑴ 因为抽象类不能定义对象,所以抽象类只能做父类、不能做派生类。
⑵ 因为抽象类不能定义对象,所以抽象类中不能有数据成员。
⑶ 因为抽象类不能定义对象,所以抽象类不可以是函数的返回类型。
⑷ 因为抽象类不能定义对象,所以尽管抽象类中有数据成员,抽象类的派生类对象中不继承抽象类的数据成员。
8 因为友元成员不是本类的成员,所以 。
⑴ 友元成员没有对应的this指针。
⑵ 友元不能访问本类的父类的任何成员。
⑶ 友元不能修改本类数据成员。
⑷ 友元至少有一个参数,而且其类型是本类型。
9 一个被调用的inline函数的定义与调用该inline函数的函数分别写在不同的源文件中,如果inline函数的代码一旦有所改变,下面 说法是正确的。
⑴ 所有调用该函数的代码必须重新编译。
⑵ 只要重新编译该inline函数即可,所有调用该函数的代码不必重新编译。
⑶ inline函数和调用该函数的代码都不必重新编译,因为inline函数实际上不是函数。
⑷ 因为inline函数实际上不是函数,所以inline函数的代码是否改变无关紧要。
10基类的析构函数最好定义成虚函数,因为 。
⑴ 在进行多态处理时,基类的析构函数如果不是虚函数,就无法析构派生类对象。
⑵ 在进行多态处理时,不需要调用父类的析构函数。
⑶ 父类的虚函数可以被继承。
⑷ 虚函数可以被派生类重载。
四 填充题(每小题1分,共10分)
1 在C++ 中,不同类型的指针之间不能相互赋值,但只有 类型的指针例外。
2 在C++ 中,指针的值不是整型,所以整型数据不能赋值给指针,但只有整型数 可以赋值给任何类型的指针。
3 用new创建的、由局部指针对象指出的对象的作用域是 。
4 在类的成员函数中,什么被认为是隐含的内联函数? 成员函数。
5 一个声明、后定义的函数,如果要使其成为内联函数,则必须在 时冠以inline,否则编译程序不认为是内联函数。
6 对于有继承关系的类,父类子对象的初始化只能在直接派生类的 中进行,而不可以在直接派生类的构造函数的函数体中进行。
7 一个函数的 ,实际上是起到多个函数重载的作用。
8 在C++ 异常处理机制中,被throw语句抛出的异常,只有当该throw语句在 语句块的控制范围内,才会被捕获。
9 某个操作符重载后,其原来的优先级和结合性 。
10父类的指针指向派生类的对象,以实现 。
五 是非题(每小题1分,共10分)
1 一个类的所有对象都具有相同的数据结构和操作。
⑴ 是 ⑵ 非
2 类的static成员不是属于某个对象的、而是所有对象共享的,因此系统对具有static成员的类就不提供this指针。
⑴ 是 ⑵ 非
3 在同一程序中的所有同名函数都是函数重载。
⑴ 是 ⑵ 非
4 纯虚函数绝对不可以有函数定义。
⑴ 是 ⑵ 非
5 int x=7,&xx=x; 此xx是x的“引用”,系统不为xx分配整型数据的内存空间,所以xx不可以做左值。
⑴ 是 ⑵ 非
6 构造函数的作用是创建和初始化对象,而构造函数又是公有成员函数,所以,要创建多个新的对象,只要通过某个对象多次调用构造函数即可。
⑴ 是 ⑵ 非
7 析构函数的作用是“消除”对象,因此,如果要使某个对象“消失”,只要调用析构函数即可。
⑴ 是 ⑵ 非
8 一个对象可以有多个“引用”。
⑴ 是 ⑵ 非
9 加以const限定的对象是常量,所以不能对const对象进行取址。
⑴ 是 ⑵ 非
10 C++允许一行写多条语句,但是预编译指令必须单独占有一行。
⑴ 是 ⑵ 非
六 编程题(共30分)
现有如下的main()函数,成员函数的功能见说明。请用面向对象的软件“复用”技术设计并定义Shape、Point、Triangle、Rectangle、Cubic,致使能正确运行如下的main()函数。说明:
函数getTypeName() 的功能是输出pS所指向的对象的类型名;
函数pS->getValue() 的功能是输出pS指向的对象的数据成员值;
函数pS->calArea() 的功能是计算并输出pS指向的对象的面积;
函数pS->calVolume() 的功能是计算并输出pS指向的对象的体积。
void main()
{ Shape* pS = NULL; //定义Shape类的指针pS
//创建4个点(2个数据分别为x,y的坐标值):
Point p1(0,0),p2(100,0),p3(100,50),p4(0,50);
Triangle t1(p1,p2,p3); //用3点创建一个三角形对象
Rectangle r1(p1,p2,p3,p4); //用4点创建一个矩形对象
int h=100 ;
Cubic c1(p1,p2,p3,p4,h); //创建一个立方体对象,h为高
pS = &p1; //指针pS指向Point的对象p1
pS->getTypeName();
pS->getValue();
pS = &t1;
pS->getTypeName();
pS->getValue();
pS->calArea();
pS->calVolume();
pS = &r1;
pS->getTypeName();
pS->getValue();
pS->calArea();
pS->calVolume();
pS = &c1;
pS->getTypeName();
pS->getValue();
pS->calArea();
pS->calVolume();
}
//注意:输出结果必须可理解。 |
|