搜索
您的当前位置:首页上海大学 面向对象的程序设计 答案

上海大学 面向对象的程序设计 答案

来源:飒榕旅游知识分享网
雷电老师的上机实验答案(部分)。以下文字中,红色为应填入的答案,绿色为代码的注释,蓝色为老师没有讲过的知识补充,紫色为我不确定的题目

☆第二章 从C到C++

1. 以下说法正确的有

A. 面向对象程序设计的基本特征是封装、继承、多态 B. 名字空间的作用是提供逻辑分类和防止名字冲突

2. 代码填空

#include using namespace std;//这是因为std涵盖了标准C++的定义和声明,可以把std想象成一个很大的名字空间名,cin、cout都是其内部定义的函数 namespace myLib //此处定义了名叫“myLib”的名字空间 { int maxV(int& a,int& b) { return a>b?a:b; }

} //此空间里面的所有函数的全名为:myLib::maxV int main( ) { int x,y;

cin >>x>>y;//因为题目要求要输入两个函数,所以我们采取依次输入

的方法

cout <过的函数,全名为:“名字空间名::函数名”

return 0; }

输入 1 2 输出 2 //maxV函数的意思是取两个参数中较大的一个

△这里说一下typedef的两条用法,下面的题目要用到:

用途一:

定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, // 和一个字符变量; 以下则可行:

typedef char* PCHAR; // 一般用大写

PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针 虽然:

char *pa, *pb;

也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。

用途二:

用在旧的C代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如: struct tagPOINT1 {

int x; int y; };

struct tagPOINT1 p1;

而在C++中,则可以直接写:结构名 对象名,即: tagPOINT1 p1;

估计某人觉得经常多写一个struct太麻烦了,于是就发明了: typedef struct tagPOINT {

int x; int y; }POINT;

POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候

或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。

3. 有函数

typedef char* LPTSTR; //此处规定了LPTSTR的类型是一个字符型的指针,这里为typedef的用途一

int GetSystemDirectory( LPTSTR lpBuffer, int uSize);//函数中的两个参数类型,第一个为字符型的指针,第二个为整型 正确的调用代码是(多选) A. char dir[200]; GetSystemDirectory( dir, 200 );//dir[200]表示一个数组,dir也可以理解为该数组第一个成员的地址(类似于指针)

B. char *pdir=new char[200]; GetSystemDirectory( pdir, 200 );//前半句定义了一个字符型的指针pdir并且动态创建了一个长度为200的字符型数组,所以可以满足后半句中函数参数的要求 C. char *dir; GetSystemDirectory( dir, 200 );//前半句定义了一个字符型的指针dir,但是为什么不选这项我也不清楚,我要问问老师 D. string dir; GetSystemDirectory( dir, 200 );//dir的类型是一个字符串型的,不满足函数参数的要求

E. LPTSTR lpBuffer; GetSystemDirectory( dir, 200 );//dir不知道从何而

来,前半句定义lpBuffer为一个LPTSTR(字符类型的指针,为什么?看这道题的第一个注释)类型,并没有提到dir

4. 有函数

typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth;

WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond;

WORD wMilliseconds;

} SYSTEMTIME, *LPSYSTEMTIME; //此处用到了typedef的用途一:SYSTEMTIME和*LPSYSTEMTIME两者等价,类型都为结构体_SYSTEMTIME,只是SYSTEMTIME定义的变量为结构体_SYSTEMTIMELE类型,而LPSYSTEMTIME定义的变量的指针为结构体_SYSTEMTIME类型

void GetSystemTime( LPSYSTEMTIME lpSystemTime );//此处要求lpSystemTime为结构体_SYSTEMTIME的指针 正确的调用代码是(多选)

A. LPSYSTEMTIME time; GetSystemTime( time );//用LPSYSTEMTIME定义变量的形式为LPSYSTEMTIME * time,所以题目中time不是一个指针类型 B. SYSTEMTIME *ptime; GetSystemTime( ptime); C. SYSTEMTIME time; GetSystemTime( &time );

D. SYSTEMTIME *ptime=new SYSTEMTIME; GetSystemTime( ptime);

5.根据下面的调用 char str[200]; bool ok = getstr( str,200); //①我们观察getstr函数里面的两个参数:str是一个大小为200的数组的数组名,同时也是指向这个数组第一个元素的指针名(基地址);200为这个数组的元素个数,也同时是这个数组表示的存储空间里面基地址的偏移量 ②可以观察到ok的类型是bool型,所以函数getstr也应为bool型 写出其函数原型(多选)

A. void getstr( char str,int size );//不符合② B. bool getstr( char str[],int size ); C. bool getstr( char *p,int len );

D. ok=getstr( str,200 );//函数原型应包括函数得到类型

6.下面哪条代码是错误的?

A. string s; s=\"i love C++\"; cout<//p33的2.5.5,明确说明了赋值时,左边必须是一个string类型得到字符串,右边可以是一个string类型的字符串,也可以是一个C风格的字符串或仅仅是一个char字符

C. string s; s=\"i love \"; s+=\"C++\"; cout<D. string s=\"i love you\//同上

7.如下代码的输出是 p.x=4 p.y=-11 //注意cout输出内容的格式,不要忘记“p.x=”,“p.y=” #include using namespace std; struct point { int x,y; };

void move (point& q) { q.x--; q.y++; }

int main() {

point p; p.x=5; p.y=-12; move(p);

cout<<\"p.x=\"<8.如下代码的输出是 *p.x=4 *p.y=-11 #include using namespace std; struct point {

int *x,*y; };

void move (point& q) {

--*q.x; //此处是将q.x所指向的内容自减1 ++*q.y; //此处是将q.y所指向的内容自增1 }

int main() {

point p;

int a=5,b=-12;

p.x=&a; //此处,令a的地址为p.x p.y=&b; //此处,令b的地址为p.y

move(p);

cout<<\"*p.x=\"<<*p.x<<'\\n'; cout<<\"*p.y=\"<<*p.y<<'\\n'; return 0; }

9.写一段代码 double * db_ptr = new double;

分配一个类型为double的存储空间,并将它的地址赋给变量db_ptr //此题代码也可为: double * db_ptr;

db_ptr = new double;

10.下面代码输出为 5 ,有一行错误修改为: int & ai(int i) { int j=1;改为static int j=1;//因为代码定义了一个引用返回类型,j和b直接关联在一起,没改之前,当return j时,存储j的空间已经收回,所以要把j改为静态(全局)变量 j += i; return j; }

int main() {

int& b=ai( 1 ); b++;

b = ai( 2 ); cout<11.下面代码填空 //此题主要是考枚举的概念,p28 2.4.4 #include using namespace std;

enum {MinSize=0,MaxSize=1000};

enum Color{red=0xff0000,green=0xff00,blue=0xff}; void draw( Color color) { if(color==red) cout<<\"红\"<int main(int argc, char* argv[]) {

int a[MaxSize]; for(int i=0;i12.下面代码的输出 er:越界! 0 1 2 const int MaxSize=3; int curr=0;

int A[MaxSize]; void append(int x) { if( currint main(int argc, char* argv[]) { int i; try { for(i=0;i<5;i++) append(i); } catch(char *e) { cout<//此题考察例外处理,p53 2.8 ☆第三章 类

类(1)

设计并实现类(P127 3-7)

1. 填空

class Profession { string name; string title; double avgIncom; public: Profession(){} //构造函数 Profession(string name){ this->name=name;} //构造函数 ~Profession(){} //析构函数 int CompareIncome( Profession &profes) { if( this->avgIncom < profes.getavgIncom()) return -1; else if(this->avgIncom == profes.getavgIncom() )return 0;

//根据main函数最后输出结果的形式得出,特别注意C++的等于用“==”表示

else return 1; } static int CompareIncome( Profession &profes1,Profession &profes2) { if(profes1.getavgIncom()< profes2.getavgIncom() ) return -1; else if( profes1.getavgIncom()> profes2.getavgIncom()) return 1; else return 0; } string getname(){return name;}//name是字符串类型 string gettitle(){return title;} double getavgIncom(){return avgIncom;}//avgIncom是double型 void setname( string name ) { this->name =name;}//表示Profession

类里面定义的name被setname的参数赋值

void settitle( string title ) { this->title=title;} void setavgIncom( double avgIncom ) { this->avgIncom=avgIncom;}

};

int main( ) { Profession prof[2]; for(int i=0;i<2;i++) { string name; string title; double avgIncom; cin>>name>>title>>avgIncom; prof[i].setname(name);//在循环中对两个prof都进行

setname操作,但是要它们自己调用自己的成员函数setname

prof[i].settitle(title); prof[i].setavgIncom(avgIncom); } for(i=0;i<2;i++) {

cout<} int comp= Profession::CompareIncome( prof[0],prof[1] ); //用到Profession类里面的函数,调用方法就为以上形式 cout< 0 ) cout<<\"多\"<2. 改写settitle成员函数为外式实现 void Profession::settitle( string title ) { this->title=title;} //因为是外联式实现(写在类外面),所以要用到“::”域解析操作符

3. 改写析构函数为外联式实现 Profession::~Profession(){}

//同理

4. 考察main()函数中的调用代码:prof[i].settitle(title);

设对象prof[0]的地址0x11234567,对象prof[1]的地址0x21234567那么运行分别进入成员setname函数体中,

this值分别是0x11234567 、0x21234567

//p119 最右边有■的一句话:this指向对象c1,即this的值为&c1 类(2)

以下是 第3章 类 教材中的练习

1. 78页 3.1.8-2 Airplane airplane; (注:对象名airplane) Airplane airplanes[5]; (注:5个对象的数组,名airplanes)

2. 79页 3.1.8-5 //与struct区别开来,struct成员都是公有的 A.私有 B.公有

3. 79页 3.1.8-9 改为 //此题牵涉到成员函数外联实现的表现形式 A. private: unsigned getHeadCount() const; B. unsigned Circus::getHeadCount() const { ... } C. Circus:: unsigned getHeadCount() const { ... } D. unsigned Circus::getHeadCount() { ... } 4. 82页 3.2.7-2 getTop其声明及内联式的实现(注:不考虑栈可能是空的情况)

int getTop() {return arr[top];} //所写代码只要满足要求即可

5. 85页 3.3.5-5 错的地方修改为 A. void setAux(string& s){ dm=s;} B. void setAux(const string& s) const { dm=s;} C. void set(string& s)const{ setAux( s ); } D. void set(const string& s) { setAux( s ); } //修改之前set函数使用const标记的,而setAux是非const类型,所以这种调用是错误的,具体陈述请见p84 最后一段

6. 105页 3.5.12-2 错的地方修改为Z(); //构造函数没有函数类型 7. 106页 3.5.12-7 错的地方修改为public: //构造函数需要被调用,所以必须为公有成员函数

8. 106页 3.5.12-9 错的地方修改为R(const R&arg); (注:参量要使用const修饰) //拷贝构造函数的定义,p95 3.5.4

9. 106页 3.5.12-13 输出 1 -999 //这道题要说明什么我也不清楚

10. 107页 3.5.12-19 错的地方修改为

A. public: void C( int a ) { c = a; } B. const int c = 0; C. public: const int c; D. public: C( int a ) c(a) { }

//此题表示的是,当要对const类型的对象赋值时,不能直接在函数内部赋值,需要用到构造函数的初始化段

11. 108页 3.5.12-22 错的地方修改为~A(); //析构函数没有函数类型

12. 117页 3.7.4-3 补上所缺的代码 int C::x=0; (注:设初值为0)

//因为x为static类型,属于全局变量,所以可以在类的外面对x赋值,但要用到“::”域解析操作符

13. 117页 3.7.4-4 错误地方修改为 A. ++this->x B. this->++x C. s函数内不能访问x D.public: int x;

//static函数不能访问非static内容,具体陈述见p155 中间一段

14. 117页 3.7.4-5 输出 1 2 3 //s为static类型,属于全局变量

15. 120页 3.8.2-1 错的地方修改为 A.void g( C& c1); B.g(c1); C.p->m(); D.c1.g(&c1); //必须用这种形式,p118 例3-42

以下是自编练习:

16. 设有 class CC { public: CC( int x ){} }; 以下创建对象的方法正确的有(多选) A. CC c(1); B. CC *pc=new CC(1); C. CC cs[2]={C(1),C(2)}; D. CC c; E. CC cs[2]={1,2}; F. CC c1(1); CC c2(c1);

//因为构造函数带有参数,所以创建对象时,必须要带参数创建,所以只有D没有带参数,故选ABCEF

17. 设有 class CC{ public: void m(); static void sm(); int a; static int s;}

以下正确的有(多选) A. CC c; c.m(); c.sm(); B. CC c; CC::m(); c.sm(); C. CC c; c.m(); CC::sm(); D. CC c; CC::m(); CC::sm(); E. int CC::s=0; F. void CC::sm(){ s=9;} G. void CC::m(){ this->s=9;} H. void CC::sm(){ this->a=9;} //见p115 例3-39 后面有一个表格,说明了当成员函数是static类型时,可以用C::sm()调用,也可以用c.sm()调用;当成员函数非static类型

时,只能用c.m()调用。故B、D错误,另static成员函数只能访问static成员,a为非static类型,所以H错误

☆第四章 继承

1. 137页 4.2.5-1 2 (个)。//本身有一个y,又从A类继承了一个x

2. 137页 4.2.5-2 错的地方可修改为(多选) A. public:int x; B. public:int y;

C. protected:int x; D. protected:int y;

//若x为私有成员变量,派生类的成员函数不能对其进行访问

3. 137页 4.2.5-3

A. P->Q->R B.R->Q->P

//P,Q为分别继承Q,R得来,故P,Q分别为Q,R子类,则P->Q ,Q->R 4. 144页 4.4.1-4 2(个)。

//x为私有成员变量,派生类对其不可见

5. 144页 4.4.1-5 错的地方可修改为

A. public:int x; B. public:void set_x(int a){x=a;} C. protected:int x; D. protected:void set_x(int a){x=a;} E. a1->set_x(4); F. protected:void set_x(int a){a=x;}

//要调用成员函数set_x(4),那么他首先必须是一个公有成员函数

6. 144页 4.4.1-6 错的地方可修改为(多选)

A. public:int x; B. public:void set_x(int a){x=a;}

C. public:void f(A& a){this->set_x(5);} D. public:void f(A& a){ a->set_x(5);}

7. 145页 4.4.1-7 填写DC::init函数体代码 set1(n1); set2(n2); num3=n3;

8. 152页 4.5.4-1 错的地方可修改为(多选)

A. 在类BC中添加public成员BC(){} B. DC(int a):BC(a){ /*constructor body*/}

C. 在类BC中删除构造函数

//创建对象时,依据派生类要调用的构造函数类型(参数类型),调用基类的构造函数,若基类没有这一类型就会出错 9. 152页 4.5.4-2 因为

A. 在Primate构造函数被调用时Animal构造函数会被先调用 B. 没关系.

//继承机制下创建派生类对象:从最顶层类中调用构造函数,依次调用下来

10. 152页 4.5.4-3 (注:省写constructor,以空格分隔) BC b; 执行后输出 BC

DC1 d1; 执行后输出 BC DC1

DC2 d2; 执行后输出 BC DC1 DC2

return 0;执行后输出 DC2 DC1 BC DC1 BC BC

//继承机制下创建派生类对象:从最顶层类中调用构造函数,依次调用下来;

当要释放对象时,从最底层类调用析构函数,依次调用上去;两者刚好相反

11. 152页 4.5.4-9 A. 是 B.否 //执行BC(int)即可

12. 164页 4.7.3-2 4(个)。//派生类的成员函数可以访问基类的保护成员变量

13. 165页 4.7.3-3 x=1; y=2; a=3; b=4; (注:按x,y,a,b顺序分别赋值1,2,3,4)

14. 165页 4.7.3-4 2(个)。//p164 第一段文字

以下是自编练习:

15. 有定义:

class BC{public:int b; void m(){cout<<\"BC\";} };

class DC : public BC { public: int d; void m(){BC::m();cout<<\"DC\";} }; void f(BC b){ } void g(BC *pB){ } void h(DC* pD);

BC bc; DC dc;

BC *pb=new DC; DC *pd=new DC; 15.1 以下代码正确的是(多选)

A. f(dc); B. g(&dc); C.h(&bc); D. pd->d = 1; E. pb->d = 1;

F. DC *p=pb; G. DC *pdc=(DC*)pb; pdc->d = 1; dc.m();执行后输出 BCDC dc.BC::m();执行后输出 BC

16. 下面那些是错误的?

class Base { ... };

A. class Derived : public Derived { ... }; B. class Derived : Base { ... };

C. class Derived : private Base { ... }; D. class Derived : public Base;

E. class Derived inherits Base { ... }; //继承的定义

17. 已知如下基类和派生类定义

class Base {public: foo( int ); double m_fb; protected: int m_bar; double m_foo_bar; };

class Derived : public Base { public: foo( string ); bool bar( Base *pb ); void foobar( ); protected: string m_bar;}; 请指出下列错误代码段的修改 (多选)

17.1. Derived d; d.foo( 1024 ); AC //1024为int型,而派生类中foo(string)覆盖了基类中的foo(int),所以AC可以作为修改代码

17.2. void Derived::foobar() { m_bar = 1024; } D //与17.1同理,上面被覆盖的是函数,这里被覆盖的是变量

17.3. bool Derived::bar( Base *pb ){ return m_foo_bar == pb->m_foo_bar; } G //“==”两边的变量类型要一致

A. Derived d; d.Base::foo(1024 ); B. Derived d; d.foo( int ); C. Derived d; d.foo( “1024” );

D. void Derived::foobar() { Base::m_bar = 1024; } E. void Derived.foobar() { m_bar = 1024; }

F. bool Derived::bar( Base *pb ){ return Base::m_foo_bar == pb-> m_foo_bar; }

G. bool Derived::bar( Base *pb ){ return m_foo_bar == pb-> m_fb; }

18. 已知下列类层次结构以及数据成员集,赋值语句哪些是错误的

class Base1 {……. protected:int ival;double dval;char cval;private:int *id;}; class Base2 {…… protected:float fval;private:double dval;};

class Derived : public Base1 {……protected:string sval;double dval;};

class MI : public Derived, public Base2 {….public: void bar(); protected:int *ival;double cval;}; void MI::bar() {

int sval;

// 练习答案放在此处 }

A. dval = 3.14159; B. cval = 'a';

C. id = 1; D. fval = 0; E. sval = *ival; //dval和id均为私有成员变量,派生类成员函数不能访问

19. 已知下面的Base 类及其三个构造函数

class Base {….public:Base();Base( string );Base( const Base&);protected:string _name;};

请为下面的类定义相应的三个构造函数 class Derived: public Base{ ... };

A.Derived:: Derived(){Base();} B.Derived:: Derived(string s):Base(s){} C. Derived:: Derived(){ } D. Derived:: Derived(const Base& b):Base(b){}

//参数类型与父类构造函数的参数类型要一致,在子类构造函数带有参数的时

候要显式地去调用父类的构造函数 p147 4.5.2

☆ 第五章 多态

1. 180页 5.1.7-2

A.编译期绑定是在编译时,而运行期绑定是在程序运行时确定数据地址。

B.编译期绑定在编译期就确定了函数调用源代码,而运行期绑定是在程序运行时生成函数源代码。

C.编译期绑定在编译期就确定了函数调用的入口地址,而运行期绑定是在程序运行时确定函数调用的入口地址。

//与编译期绑定不同的是,运行期绑定是直到程序运行之时(而不是在编译时刻)才将函数名称绑定到其入口地址。见P172倒数二三行

2. 180页 5.1.7-3(多选)

A.有继承体系 B.有virtual成员函数 C.有static成员函数 D.是公有成员 E.通过对象的指针或引用来访问多态函数。 F.通过基类类型的指针或引用变量来访问多态函数 。

//详情见P173 C++多态的前提条件

·必须存在一个继承体系结构

·继承体系结构中的一些类必须具有同名的virtual成员函数(virtual是关键字) ·至少有一个基类类型的指针或基类类型的引用。这个指针或引用可用来对virtual成员函数进行调用。

3. 180页 5.1.7-5 修改为void hi() ; //代码段申明了f为虚函数,而hi为顶层函数,

不是成员函数,因而是错误的,应将virtual去掉

4. 181页 5.1.7-6 修改为(多选)

A. public: void m(); B.public: virtual void m();

C. void B::m(){ /*...*/} D.void virtual B::m(){ /*...*/}

//C++仅允许将成员函数定义为虚函数,顶层函数不能为虚函数

5. 181页 5.1.7-7

A.可以 B.不可以

//见P176 虚成员函数继承

和普通成员函数一样,在派生类中虚成员函数也可以从基类继承

6. 181页 5.1.7-8 D::m()

//系统将函数调用p->m( );绑定到虚函数表中的某一项,系统首先决定指针p指向哪个对象,如果p指向d1,系统将在虚成员函数表中查询D::m的入口地址,一旦查询完成,就可以执行相应的函数体 详见P177 例5-7

7. 181页 5.1.7-12

A.会 B.不会 C.不一定

//见P179 例5-9后的解释

8. 181页 5.1.7-13 题目修改为在下面代码中,输出结果 B class B{ public:~B(){cout<<\"B\";}};

class Z:public B{ public:~Z(){cout<<\"Z \";}};

int main(){ B* p=new Z; delete p; return 0; } //同上

9. 181页 5.1.7-14

A.正确 B.不正确

10. 181页 5.1.7-15 修改方法是对下面函数的定义去掉virtual关键字 A. m() B.A() C.~A()

//A( )为构造函数,将构造函数声明为虚成员函数,导致错误,但析构函数可以是虚成员函数。

11. 181页 5.1.7-16 输出结果 D

//D自身有对虚成员函数f()的定义,故直接调用自身的f()

12. 194页 5.3.5-3

A.编译期 B.运行期

13. 194页 5.3.5-5

A.编译期 B.运行期

//在进行重载时,总是使用编译期绑定,在这个方面重载函数(不管是成员函

数还是顶层函数)和虚函数是截然不同的,虚函数总是在运行期。见P190

14. 194页 5.3.5-9 输出结果 A::m

//见P190-191例5-13解释

P指向一个Z对象,而不是一个A对象,当我们通过p来调用成员函数m时。看起来像是运行期绑定,但实际上不是,因为m不是虚函数,而在C++中只有虚函数才会进行运行期绑定。编译器会使用p的数据类型A*进行绑定,结果是绑定到A::m。

15. 194页 5.3.5-10 输出结果 Z::m

16. 195页 5.3.5-11 错误的代码是 A. a1.m(); B. a1.m(3.14 );

//调用的是A的本地函数A::m

17. 195页 5.3.5-12 改写题目中的代码 A* p = new A; 为 A* p= new Z; 且在类A中添加 virtual void m(){ cout<<\"A\"; } 后不再有错误,更改后代码的输出 foo

3.14

//先调用Z的本地函数,再调用A的本地函数

18. 195页 5.3.5-13 输出 baz26 //同上 19. 199页 5.4.5-2 错误的代码是 A. A a1; B. public

//见P197例5-18 虽然不能创建一个抽象基类的对象,但抽象基类可以拥有派生类,从抽象基类派生来的类必须覆盖基类的所有纯虚成员函数,否则派生类也成为抽象类,因而也不能用来创建对象。

20. 199页 5.4.5-3 更改为

A. void A::m(){ /*... */ } B. A(){}

C. virtual void m()=0; D. virtual int x=0;

//纯虚成员的申明

21. 200页 5.4.5-5错误的代码是 A. Z z1; B. struct

22. 206页 5.5.6-1错误原因是(多选)

A. dynamic_cast使用非法 B. 类A和类C没有关系 //dynamic_cast的规则见P205 5.5.2 23. 207页 5.5.6-2错误原因是(多选)

A. dynamic_cast使用使用非法 B. 类A和类C没有关系 C.不是类型的指针或引用的转化

24. 207页 5.5.6-14 - 5.5.6-20 为真的题号是15 16 17 20(以空格分割) 为假的题号是14 18 19(以空格分割)

//参照P206 例5-30

☆第六章 操作符重载 教材中的练习

1.

223页 6.2.6-3 作为成员函数实现的重载 _____1_______

Complex Complex::operator~()const{ return Complex (real,-imag);}

2. 223页 6.2.6-4 作为成员函数实现的重载 _____1_______ (提示:double sqrt(double))

double Complex::operator!()const{ return sqrt (real*real+imag*imag);}

// Complex/ double Complex::operator符号()const{return„„}

3. 226页 6.3.1-1 A. 两操作对象不能是基本数据类型 B.不能有两操作对象

//操作符(%)要么一成员函数的形式重载,要么以顶层函数的形式重载。对于后者,将至少带有一个类对象参数

4. 226页 6.3.1-2 修改为:bool C::operator&&( C& c ){...} 后 A. 仍然错误 B.正确

//见P215 最后一段 调用operator+的语法和调用普通函数的语法相同

5. 228页 6.4.1-1 正确的修改是(多选): A. void C::operator!( C& c ){c.stored = !c.stored;} B. void C::operator!( ){c.stored = !c.stored;} C. void C::operator!( ){ stored = stored;}

D. public: bool stored;

E. class C {... 添加 friend void operator!( C& c ); }

//类的私有成员只能被该类的成员函数和该类的friend函数访问;类的保护成员只能被该类的或其派生类的成员函数和该类的friend函数访问

6. 230页 6.5.1-1 和 6.5.1-2 修改为____6__________ ; (只要写接口)

istream & operator>>( istream& in,Complex& c)

//见P229例6-11

Instream& operator>>(istream& in,Complex& c) { return in >> c.real>>c.imag; }

7. 233页 6.6.1-2 输出结果____7______

1 -999

☆第7章 模板和C++标准库 教材中的练习

1. 264页 7.1.4-4 最后2行修改为

A. template Queue:Queue(){/*...*/} B. Queue::Queue(){/*...*/}

C. template Queue::Queue(){/*...*/} D.Queue::template Queue(){/*...*/}

E. Queue::Queue(){/*...*/} F. void Queue::Queue(){/*...*/} //P259模板类Array中的转型构造函数定义如下 template Array< T >::Array( int s) {„„}

2. 264页 7.1.4-6 最后1行可修改为(多选) A. Queue q1; B. template Queue q1; C. Queue q1; D. Queue *q1 = new Queue(); E. Queue q1; F. Queue *q1 = NULL; //通过在< >中指定数据类型来使用一个模板类,对象不能属于模板类,只能属于模板实例。

3. 264页 7.1.4-11最后1行可修改为(多选) A. Queue q1; B. template Queue q1; C. Queue q1; D. Queue *q1 = new

Queue();

E. Queue q1; F. Queue *q1 = NULL;

//参照P262 例7-9中Array< double, 10>a1;

以下是自编练习

4. 请指出下列模板类声明或声明对中哪些是非法的

A. template class Container1;

template class Container1; B. template class Container2;

//模板类中的每个函数参数,不管是内置的还是自定义的,都必须在模板头中指定其数据类型

C. template class Container3 {}; D. template class Container4 {}; //不能同时对一种函数参数指定两种数据类型

E. template class Container5; template class Container5;

F. template class Container6;

template , int v> class Container6;

5.请指出下列哪些模板实例化或实现是正确的 template < class Type, int size > class Fixed_Array { void m( Type t); }; templateint SeqSearch( T list[ ], T key,int n){...} A. Fixed_Array fa;

B. int arr[10]={1}; int index = SeqSearch( a ,1,10);

C. int arr[10]={1}; int index = SeqSearch( a ,1,sizeof(arr)/sizeof(int)); D. Fixed_Array fa;

E. const int size_val = 1024; Fixed_Array< string, size_val > fa1;

F. int fasiz e = 255; Fixed_Array< int, fasize > fa2;

G. template< class Type, int size >void Fixed_Array::m(Type t){return;} H. void Fixed_Array::m(Type t){return;}

6. 下面代码,输入什么数,程序能打印输出该数。 int top; cin>>top;

assert(top==-1); cout<//用于调试,使用方法 assert ( 表达式 ); 当表达式为假,系统停止程序在该处,于是可检查调用栈各函数的执行的状态。当表达式为真,系统继续执行后面的代码。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top