内容发布更新时间 : 2024/11/17 6:38:10星期一 下面是文章的全部内容请认真阅读。
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页