中南大学考试试卷

一、选择题(单选)(每空1分,共11分)

1、已知X类,则当程序执行到语句X array[3];时,调用了( )次构造函数。

A.0 B.1 C.2 D.3

2、假定TT为一个类,则该类的拷贝构造函数的声明语句为( )。

A.TT (TT x) B.TT& (TT x) C.TT (TT &x) D.TT (TT *x)

3、已知:int m=10; 下列表示引用的方法中,( )是正确的。

A.int &x=m; B.int &y=10; C.int &z; D.float &t=&m;

4、不能说明为虚函数的是( )。

A.析构函数 B.构造函数 C.类的成员函数 D.以上都不对

5、在C++中,用于实现动态多态性的是( )。

A.内联函数 B.重载函数 C.模板函数 D.虚函数

6、下列关于类和对象的叙述中,错误的是( )。

A.一个类只能有一个对象 B.对象是类的具体实例

C.类是对某一类对象的抽象 D.类和对象的关系是一种数据类型与变量的关系

7、关于友元函数的描述中,错误的是( )

A. 友元函数不是成员函数 B. 友元函数只能访问类中私有成员 C. 友元函数破坏隐藏性,尽量少用 D. 友元函数说明在类体内,使用关键字friend

8、下列运算符中,( )运算符在C++中不能被重载。

A.&& B.[] C.new D.? :

9、类模板的使用实际上是将类模板实例化成一个( )。

A.函数 B.对象 C.类 D.抽象类

10、已知如下类层次定义 class X { ... };  class A { ... };  class B : public A { ... };  class C : private B { ... }; class D : public X, public C { ... }; 当定义了 D *pd = new D; 下列哪两项( )和( )转换是不允许的

  1. X px = pd;  (b) A pa = pd;   (c) B pb = pd;   (d) C pc = pd;

1)D.3。在语句 X array[3]; 中,如果 X 类有构造函数,则调用 X 类的构造函数来初始化数组 array 的每个元素。因为数组大小为 3,所以会调用 3 次构造函数。

2)C.TT (TT &x)。拷贝构造函数的声明语句是 TT (TT &x),表示接受一个引用参数。

3)A.int &x=m;。这是正确的引用声明,将 x 绑定到 m 的地址。

4)B.构造函数。构造函数不会被声明为虚函数,因为它们在对象创建时被调用,根据对象的实际类型进行调用,而不是根据指针或引用的类型。

5)D.虚函数。虚函数用于实现动态多态性,允许在运行时根据对象的实际类型调用相应的函数版本。

6)A.一个类只能有一个对象。这个叙述是错误的,一个类可以有多个对象。

7)A.友元函数不是成员函数。友元函数不是类的成员函数,但可以访问类的私有成员。

8)D.? :。条件运算符 ? : 不能被重载。

9)C.类。类模板的使用实际上是将类模板实例化成一个类。

10)B、C。转换 (b) 和 (c) 是不允许的。因为 D 类的继承结构中 B 类是 private 继承,所以 D 类对象的指针不能直接转换为 B 类或 A 类的指针。


二、填空题(每空1分,共5分)

1. 面向对象程序设计有4个主要特点: (1) 、 (2) 、(3) 、 (4) 。

2. 后置自增运算符“++”重载为类的成员函数(设类名为A)的形式为: (5) 。

(1) 抽象 (2)封装 (3)继承 (4)多态性  (5) A operator++(int)


三、判断题(每小题1分,共15分)

1. 类必须编写至少一个构造函数。

2. 友元函数说明在类体内,它是一种成员函数。

3. 构造函数的名字必须与类名相同,其返回类型缺省为void类型。

4. 运算符重载以后,其优先级和结合性都不能改变。

5. 默认构造函数的形参列表中没有形参。

6. 纯虚函数是在基类中说明的虚函数,它在该基类中没有定义具体的操作内容。

7. C++能对已有的运算符进行重载,同时允许用户自己定义新的运算符。

8. 常对象只能调用它的常成员函数, 而不能调用普通的成员函数。

9. 类静态成员数据为该类所有对象共享,在该类对象被撤销时,静态成员并不撤销。

10. 如果一个类没有自定义默认构造函数,则编译器会自动生成一个。

11. 在声明一个类时,必须同时声明类的数据成员和成员函数。

12. cin 是 istream 类的成员函数。

13. 具有转换函数功能的构造函数,是指只能带有一个或两个参数的构造函数。

14. 析构函数的作用是当对象不用时,删除对象。

15. 运算符函数可以重载为成员函数,也可能重载为友元函数或者普通函数。

1)×。类不一定要编写构造函数。如果没有显式定义构造函数,编译器会生成一个默认构造函数。

2)×。友元函数不是类的成员函数,它不属于类的任何一个成员函数,虽然可以在类的内部声明,但它并不是类的成员。

3)×。构造函数的名字必须与类名相同,但构造函数没有返回类型,包括 void。

4)√。运算符重载后,其优先级和结合性保持不变。

5)×。默认构造函数是一个不带参数的构造函数,因此形参列表中不包含任何形参。

6)√。纯虚函数在基类中声明为虚函数,但没有定义具体的操作内容。

7)×。C++只能对已有的运算符进行重载,不能自定义新的运算符。

8)√。常对象只能调用它的常成员函数,而不能调用普通的成员函数。

9)√。类的静态成员数据为该类的所有对象共享,不会因为对象的撤销而撤销。

10)×。如果一个类没有定义任何构造函数,编译器会默认生成一个无参的默认构造函数。如果类定义了其他构造函数,编译器就不会再生成默认构造函数了。

11)×。在声明一个类时,只需声明类的成员函数和数据成员的原型,不需要同时定义它们的具体实现。

12)×。cin 是 istream 类的对象,不是它的成员函数。

13)×。具有转换函数功能的构造函数可以带有一个参数或多个参数,并且通常只有一个参数是常用的。

14)×。析构函数的作用是当对象不用时,释放对象所占用的资源,而不是删除对象本身。

15)√。运算符函数可以重载为成员函数,也可以重载为友元函数或普通函数。


四、问答题:什么是this指针,它有何作用? (6分)

在每一个成员函数中都包含一个特殊的指你针,这个指针的名字是固定的,称为this指针,它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址,这样同一个类创建的多个对象共用同一份成员函数的拷贝,也知道是取哪一个对象的成员数据。

五、综合题(第1小题5分,第2小题4分,第3小题4分,共13分)

已知如下的类继承层次,解答后面的3个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Base1 {
public:
Base1() {
cout << "Base1" << endl;
}
~Base1() {
cout << "~Base1" << endl;
}
};

class Base2 : public Base1 {
public:
Base2() {
cout << "Base2" << endl;
}
~Base2() {
cout << "~Base2" << endl;
}
};

class Derived1 : virtual public Base2 {
public:
Derived1() {
cout << "Derived1" << endl;
}
~Derived1() {
cout << "~Derived1" << endl;
}
};

class Derived2 : virtual public Base2 {
public:
Derived2() {
cout << "Derived2" << endl;
}
~Derived2() {
cout << "~Derived2" << endl;
}
};

class MI : public Derived1, public Derived2 {
public:
MI() {
cout << "MI" << endl;
}
~MI() {
cout << "~MI" << endl;
}
};

class Final : public MI, public Base1 {
public:
Final() {
cout << "Final " << endl;
}
~Final() {
cout << "~Final " << endl;
}
};
  1. 定义一个Final 类对象引起的构造函数和析构函数的调用顺序如何?

构造函数调用顺序:Base1、Base2、Derived1、Derived2、MI、Base1、Final

析构函数调用顺序:~ Final、Base1、MI、Derived2、Derived1、Base2、Base1

  1. 一个Final 类对象含有多少个Base1 子对象? 含有多少个Base2 子对象?

一个Final 类对象含有2个Base1 子对象,含有1个Base2 子对象

  1. 下面的程序段①-④行中哪2行赋值会引起编译时刻错误?并解释错误原因。

Base2 *pb;

MI *pmi;

Base1 *pc;

Derived2 *pd2;

① pb = new Base1;

② pd2= new Final;

③ pmi = pb;

④ pd2 = pmi;

①③有错误,只能用基类指针指向派生类对象,反之不可以(除非进行强制转化可以通过编译,但是后续运行时一般引起错误)。