中南大学考试1
中南大学考试试卷1
一、选择题(单选)(每空1分,共15分)
1、在C++中,用于实现动态多态性的是( )。
A.内联函数 B.重载函数 C.模板函数 D.虚函数
2、下列关于类和对象的叙述中,错误的是( )。
A.一个类只能有一个对象 B.对象是类的具体实例
C.类是对某一类对象的抽象 D.类和对象的关系是一种数据类型与变量的关系
3、关于友元函数的描述中,错误的是( )
A. 友元函数不是成员函数 B. 友元函数只能访问类中私有成员
C. 友元函数破坏隐藏性,尽量少用 D. 友元函数说明在类体内,使用关键字friend
4、下列运算符中,( )运算符在C++中不能被重载。
A.&& B.[] C.new D.? :
5、模板的使用实际上是将类模板实例化成一个( )。
A.函数 B.对象 C.类 D.抽象类
6、要求通过函数来实现一种不太复杂的功能,并且要求加快执行速度,选用( )。
A. 内联函数 B. 重载函数 C. 递归调用 D. 嵌套调用
7、下面对模板的声明,正确的是( )。
A. template
C. template<class T1, class T2> D. template<class T1; class T2>
8、已知:print( )函数是一个类的常成员函数,它无返回值,下列表示中,( )是正确的。
A. void print( ) const; B. const void print( );
C. void const print( ); D. void print(const);
9、已知X类,则当程序执行到语句X array[3];时,调用了( )次构造函数。
A.0 B.1 C.2 D.3
10、假定TT为一个类,则该类的拷贝构造函数的声明语句为( )。
A.TT (TT x) B.TT& (TT x) C.TT (TT &x) D.TT (TT *x)
11、在表达式
x+y*z
中, + 是作为成员函数重载的运算符,*
是作为非成员函数重载的运算符。则 operator+ 有
个参数,operator*
有 参数。( )
A. 2、2 B. 2、1 C. 1、1 D. 1、2
12、下面( )的叙述不符合赋值兼容规则。
A. 派生类对象可以赋值给基类对象 B. 基类对象可以赋值给派生类对象
C. 派生类对象可以初始化基类对象 D. 派生类对象的地址可以赋值给指向基类指针
13、已知:int m=10; 下列表示引用的方法中,( )是正确的。
A.int &x=m; B.int &y=10; C.int &z; D.float &t=&m;
14、不能说明为虚函数的是( )。
A.析构函数 B.构造函数 C.类的成员函数 D.以上都不对
15、下列情况中,哪一种情况不会调用拷贝构造函数 ( )
A.派生类对象去初始化基类对象时 B.函数返回值是类对象,函数返回时
C.函数形参是类对象,调用函数时 D.类对象赋值给该类的另一个对象时
解释如下: 以下是对这些选择题的答案和解释:
- 在C++中,用于实现动态多态性的是( )。
- D.虚函数
- 解释:虚函数(virtual functions)是用于实现动态多态性(即运行时多态性)的。在基类中声明虚函数,派生类可以重写这些虚函数,当通过基类指针或引用调用该函数时,将执行派生类的版本。
- 下列关于类和对象的叙述中,错误的是( )。
- A.一个类只能有一个对象
- 解释:一个类可以有多个对象。对象是类的实例,一个类可以实例化多个对象。
- 关于友元函数的描述中,错误的是( )
- B. 友元函数只能访问类中私有成员
- 解释:友元函数可以访问类的私有和保护成员,而不仅仅是私有成员。
- 下列运算符中,( )运算符在C++中不能被重载。
- D.?:
- 解释:三元条件运算符(?:)不能被重载。而其他运算符如
&&
、[]
、new
都可以被重载。
- 模板的使用实际上是将类模板实例化成一个( )。
- C.类
- 解释:类模板实例化的结果是一个类。函数模板实例化的结果是一个函数。
- 要求通过函数来实现一种不太复杂的功能,并且要求加快执行速度,选用(
)。
- A. 内联函数
- 解释:内联函数通过在调用处展开代码,避免了函数调用的开销,从而加快执行速度。
- 下面对模板的声明,正确的是( )。
- C. template<class T1, class T2>
- 解释:模板声明中,多个模板参数之间用逗号分隔,并且每个模板参数都需要使用
class
或typename
关键字。
- 已知:print(
)函数是一个类的常成员函数,它无返回值,下列表示中,(
)是正确的。
- A. void print( ) const;
- 解释:
const
修饰符放在函数签名的末尾,表示这是一个常成员函数。
- 已知X类,则当程序执行到语句X array[3];时,调用了(
)次构造函数。
- D.3
- 解释:声明一个包含3个对象的数组时,会调用3次构造函数,分别构造每个对象。
- 假定TT为一个类,则该类的拷贝构造函数的声明语句为(
)。
- C.TT (TT &x)
- 解释:拷贝构造函数的参数是当前类类型的引用,以避免无限递归调用拷贝构造函数。
- 在表达式 x+
y*z
中, + 是作为成员函数重载的运算符,*
是作为非成员函数重载的运算符。则 operator+ 有 个参数,operator*
有 参数。( )- D. 1、2
- 解释:成员函数形式的
operator+
有一个参数(另一个操作数隐含为this
),非成员函数形式的operator*
有两个参数。
- 下面( )的叙述不符合赋值兼容规则。
- B. 基类对象可以赋值给派生类对象
- 解释:基类对象不能赋值给派生类对象,因为派生类可能包含基类对象所没有的成员,无法进行安全的赋值。
- 已知:int m=10; 下列表示引用的方法中,(
)是正确的。
- A.int &x=m;
- 解释:引用必须用已有的变量初始化,并且引用类型必须与被引用对象类型相同。
- 不能说明为虚函数的是( )。
- B.构造函数
- 解释:构造函数不能被声明为虚函数。析构函数和其他成员函数都可以声明为虚函数。
- 下列情况中,哪一种情况不会调用拷贝构造函数 ( )
- D.类对象赋值给该类的另一个对象时
- 解释:赋值操作调用的是赋值运算符,而不是拷贝构造函数。拷贝构造函数在对象初始化时(如函数传参、返回值)调用。
二、填空题(每空1分,共15分)
1. 后置自增运算符“++”重载为类的成员函数(设类名为A)的形式为: (1) 。
2. 若要把void fun(B &b)定义为类B的友元函数,则应在类定义中加入语句 (2) 。
3. 面向对象程序设计有4个主要特点: (3) 、 (4) 、(5) 、 (6) 。
4. 如果只想对公共基类构建一次,就必须使用关键字 (7) 把这个公共基类声明为虚基类。
5.
在C++中,三种继承方式的说明符号为 (8) 、 (9) 、 (10)
,如果不加说明,则默认的继承方式为 (11) 。
6. 如果需要在被调函数运行期间,改变主调函数中实参变量的值,则函数的形参应该是(12) 类型或 (13) 类型。
7. 在图1中,A,B,C,D,E,F均是类,其中属于单继承的派生类有(14) ,属于多继承的派生类有 (15)
这些填空题的答案是:
- (1)A operator++(int)
- 这表示后置自增运算符 "++" 被重载为类 A 的成员函数形式。
- (2)friend void fun(B &b)
- 这表示将
void fun(B &b)
定义为类 B 的友元函数,需要在类定义中加入该语句。
- 这表示将
- (3)抽象 (4)封装 (5)继承 (6)多态性
- 这些是面向对象程序设计的四个主要特点,它们可以以不同的顺序进行描述。
- (7)virtual
- 这表示使用关键字 "virtual" 将公共基类声明为虚基类,以便只对其构建一次。
- (8)public (9)private (10)protected (11)private
- 这些是 C++ 中三种继承方式的说明符,以及默认的继承方式。
- (12)指针 (13)引用
- 这表示如果需要在被调函数运行期间改变主调函数中实参变量的值,函数的形参可以是指针类型或引用类型。
- (14)E (15)D,F
- 这表示图中单继承的派生类为 E,多继承的派生类有 D 和 F。
三、判断题(每小题1分,共15分)
1. 纯虚函数是在基类中说明的虚函数,它在该基类中没有定义具体的操作内容。
2. 定义class时,用户自己必须定义构造函数。
3. 在C++中,定义结构体类型struct时不能有成员函数,只有class可以有成员函数。
4. 常对象只能调用它的常成员函数, 而不能调用普通的成员函数。
5. 友元函数说明在类体内,它是一种成员函数。
6. 构造函数的名字必须与类名相同,其返回类型缺省为void类型。
7. 运算符重载以后,其优先级可以改变。
8. 多继承提供了软件重用的强大功能,也增加了程序的复杂性。
9. 使用public公有继承时,基类中的私有成员在派生类中可以直接访问。
10. cin 是 istream 类的成员函数。
11. 类静态成员数据为该类所有对象共享,在该类对象被撤销时,静态成员并不撤销。
12. 在声明一个类时,必须同时声明类的数据成员和成员函数。
13. 析构函数的作用是当对象不用时,删除对象。
14. 运算符函数可以重载为成员函数,也可能重载为友元函数或者普通函数。
15. 数据流本身没有逻辑格式,数据的解释方式由应用程序的操作决定。
这些判断题的答案是:
- √ 纯虚函数是在基类中声明但没有定义具体操作内容的虚函数。
- × 定义类时,可以不定义构造函数。如果没有显式定义构造函数,编译器会生成默认构造函数。
- × 在 C++ 中,定义结构体
struct
类型时也可以有成员函数。 - √ 常对象只能调用它的常成员函数,不能调用非常成员函数。
- × 友元函数可以在类外定义,但在类内声明。它并不是类的成员函数。
- × 构造函数的名字必须与类名相同,但返回类型没有缺省值。
- × 运算符重载后,其优先级和结合性不会改变。
- √ 多继承提供了强大的软件重用功能,但也增加了程序的复杂性。
- × 使用
public
公有继承时,基类中的私有成员在派生类中是不可直接访问的。 - ×
cin
不是istream
类的成员函数,它是一个全局对象。(不是函数而是对象) - √ 类的静态成员数据在该类的所有对象之间共享,它们存在于类的整个生命周期中,不会因为类的对象被撤销而撤销。
- × 在声明一个类时,不需要同时声明类的数据成员和成员函数。它们可以在类的定义中分开声明和定义。
- × 析构函数的作用是在对象被销毁时执行必要的清理工作,而不是简单地删除对象。
- √ 运算符函数可以重载为成员函数、友元函数或普通函数。
- √ 数据流本身没有逻辑格式,数据的解释方式取决于应用程序的操作。
四、下列小程序各1个错误,指出错误行数,并进行改正(每小题4分,共8分)
原题
1 | 1、类模板的对象定义 |
改正
1. 类模板的对象定义
1 | template <class T> |
()改成<> ***
2. 包括静态函数和数据的类定义
1 | class myClass { |
静态成员函数没有this指针 ***
五、程序填空题:下列程序中缺少若干条语句,每条下划线只填一条语句(每条语句2分,共12分)
1. 下面是类Complex定义,其中重载的运算符<<输出复数表达式
1 | class Complex { |
2. 定义数组类模板。
1 | template<typename T> |
1 | template<typename T> |
六、简答题(每题3分,共12分)
1 |
|
阅读上面的程序,简答以下4个问题:
① 写出程序的运行结果。
② 该程序中共有几个对象,分别属于哪个类? 为什么在程序的开头处通过语句class B; 对类B进行声明?
③ 程序中的哪两条语句会分别调用A、B的构造函数?写出这两个构造函数。
④ 函数F是什么函数?它的作用是什么?
① 36 ② n1 和 n2 两个对象,n1属于A类,n2属于B类。
因为B类的定义在A类后,而A类中要引用B类。 ③ 语句A n1(10); 和语名 B
n2(8); A类的构造函数:A(int i) { a=i; } B类的构造函数:B(int i) { b=i;
}
④ 函数F是友元函数。 它的作用是:提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间共享数据的机制。(关键答出共享数据、或答出通过友元可以访问到封装与类A、B中的数据)
七、编程题(11分)
定义抽象基类Shape,由它派生出三个派生类:Circle(数据成员radius)、Square(数据成员side)、和Triangle(数据成员width,high),用虚函数分别计算各种图形的面积。要求用基类指针数组, 使其每一个元素指向一个派生类的对象。在main函数中定义如下对象,并计算和输出它们的面积之和:Circle circle(12.6); Square square(3.5); Triangle triangle(4.5, 8.4) ;
1 |
|
这段代码定义了一个抽象基类 Shape
,以及三个派生类
Circle
、Square
和
Triangle
,分别表示圆、正方形和三角形。每个类都实现了纯虚函数
area()
以计算各种图形的面积。在 main()
函数中创建了一个基类指针数组,每个指针指向一个派生类对象,然后通过循环计算并累加每个图形的面积,最后输出总面积。