2012级C++面向对象程序设计试题A-计算机学院2013夏_参考答案 下载本文

内容发布更新时间 : 2024/6/30 0:09:26星期一 下面是文章的全部内容请认真阅读。

2012-2013学年第2学期

2012级《C++面向对象程序设计》期末考试试题(A卷)

考试时间:2013年6月26日

参考答案

一、单选题(共12分,每题2分) D C (B) B B A

二、判断正误,对于你认为错误的论述,说明原因或举出反例。(共20分,每题2分) 1. 代码double dval; float *pi = &dval; 中会发生隐式类型转换,因此不存在语法错误。

错误。Double占8字节,float 占4字节,转换是不安全的,不会发生隐式转换,而是语法错误。

2. 已知类A,且语句const A a; a.fun( );是合法的,则fun( )一定是常成员函数。

错误。如fun()是A中的静态成员函数。

3. 类B继承类A,那么sizeof(B)的值大于sizeof(A)的值。

错误。是大于或等于

4. 单参构造函数一定可以被用来执行隐式类型转换。

错误。不一定。如用explicit修饰的构造函数,或私有的,或只声明但没有实现的。 5. 类中没有声明虚函数,则不会为该类生成虚拟表。

错误。不一定。如基类中有虚函数,则在创建该类对象时,仍会生成虚拟表。 6. 异常必须在其产生的当前函数中捕获,而不能在外层函数中捕获该异常。

错误。可以。如 try { f( ); } catch(…) {}, 如果f()中没有try_catch结构,f( )产生的异常可以被catch(…)捕获。

7. 由于抽象类不能实例化,但能派生新类,所以抽象类中的构造函数和拷贝构造函数应该是

protected的。

错误。抽象类表示一种泛化关系,其接口函数应在子类中存在,以保证接口的一致性。特别的,构造函数和拷贝构造函数应为public。

8. 虚函数可以访问虚函数和非虚函数,但非虚函数不能访问虚函数。

错误。非虚函数的非静态函数可访问虚函数。 9. 重载的析构函数应与重载的构造函数一一对应。

错误。析构函数不能重载。

10. 假设类A及其祖先类中均不含有指针型或引用型数据成员,执行代码块{ A a; A b(a); }时,

即便使用类A的缺省拷贝构造函数也可能造成内存泄露。 正确。

三、回答下列各题(每题4分,共28分)

1. 某个C++应用程序由1个.h文件和2个.cpp文件组成,各文件如下:

第1页 共5页

//fun.h class A { public: void fun(int = 0); }; // fun.cpp void A::fun(int num = 0) { /* 略 */ } //main.cpp int main( ) { A obj; obj.fun( ); return 0; } 请指出程序代码中存在哪些问题或有待改进的地方?如何改进? a) 最好在fun.h中加入包含警戒 b) fun.cpp中应#include”fun.h” c) main.cpp中应#include”fun.h”

d) fun函数的参数,在类定义和外联实现中均给出了缺省值。

2. 已知字符串类string,请说明函数void fun(string); void fun(string &); 和void fun(const

string&); 之间在语义和使用上的区别。

void fun(string); 以传值的方式传递一个字符串参数,参数匹配过程中,会调用string类的拷贝构造函数,构造一个新的字符串供fun函数存取。使用时,实参可以是任意一个string对象。实参可以是char*.

void fun(string &);以传引用的方式传递一个字符串参数,参数匹配过程中,不用调用string类的拷贝构造函数,而是直接传递一个引用,在fun中对参数的任何修改,影响原始的实参。使用时,要求实参必须是变量型。

void fun(const string&);以传引用的方式传递一个字符串参数,参数匹配过程中,不用调用string类的拷贝构造函数,而是直接传递一个引用。同时不允许在fun中对参数进行任何修改操作。使用时,实参可以是变量,也可以使const型。实参可以是char*.

3. 可以对局部对象显式调用析构函数吗?请说明理由。

不可以。若可以,就会产生诸如构造了一个对象,却调用了多次析构函数的情形。所以禁止显式调用析构函数。 4. 请问如何修改类A的设计,使得既可以在类外得到类A的多个实例,又能够禁止从类A

派生其它类?

class A { public: A(int n):val(n) { } private: int val; };

class A { public:

static A * CreateA(int n) { return new A(n); }

第2页 共5页

private:

A(int n):val(n) { } private: int val;

};

5. 某订单管理系统中,Customer表示客户类,Product表示产品类,ProductList表示产品列表

类,Order表示产品订单类,OrderItem表示产品订单中的条目类,OrderList表示订单列表类,请分析并给出各类之间的关系。

6. 请举例说明在哪些情况下,实现自定义构造函数必须使用初始化列表(至少给出4种)?

a) 类中含有const修饰的数据成员(常数据成员),如 const int num; b) 类中含有引用型数据成员,如 int& a;

c) 类中含有对象成员,但其类型中,没有无参构造函数,必须在初始化列表中指明相应

的有参构造函数。

d) 基类中缺少无参构造函数,必须在初始化列表中指明基类的有参构造函数。

7. 请实现派生类B的自定义拷贝构造函数和赋值函数,用于实现类B的深拷贝和深赋值。 B::B(const B& rhs) :A(rhs) { p = new int(*rhs.p); } B& B::operator=(const B& rhs) { if ( this!=&rhs) { A::operator=(rhs); delete p; p= new int(*rhs.p); } return *this; }

四、(5分)某绘图程序已存在矩形(Rect)、椭圆(Ellipse)两种图形元素。现要将三角形(Triangle)

图形元素加入该程序以实现功能扩充。已知某第三方类库中提供了XTriangle类,且完全满足程序新增的Triangle图形元素所需的功能,但XTriangle不是由Shape派生而来,而且由于缺少XTriangle类的源代码,不能从XTriangle类直接派生子类。请在下边给出的类的基础上,利用XTriangle类,定义并实现Triangle类。 class Triangle: public Shape {

public:

Triangle( ):pXtriangle(new XTriangle) { } virtual ~Triangle() { delete pXtriangle; }

virtual void Draw( ) { pXTriangle->DrawIt( ); } private:

XTriangle * pXtriangle;

};

五、(5分)现请你使用文字,描述一个实际问题,使得该问题是对应于下表中代码的一个应用例

第3页 共5页