11级OOP试题.docx

上传人:b****1 文档编号:14900790 上传时间:2023-06-28 格式:DOCX 页数:21 大小:29.71KB
下载 相关 举报
11级OOP试题.docx_第1页
第1页 / 共21页
11级OOP试题.docx_第2页
第2页 / 共21页
11级OOP试题.docx_第3页
第3页 / 共21页
11级OOP试题.docx_第4页
第4页 / 共21页
11级OOP试题.docx_第5页
第5页 / 共21页
11级OOP试题.docx_第6页
第6页 / 共21页
11级OOP试题.docx_第7页
第7页 / 共21页
11级OOP试题.docx_第8页
第8页 / 共21页
11级OOP试题.docx_第9页
第9页 / 共21页
11级OOP试题.docx_第10页
第10页 / 共21页
11级OOP试题.docx_第11页
第11页 / 共21页
11级OOP试题.docx_第12页
第12页 / 共21页
11级OOP试题.docx_第13页
第13页 / 共21页
11级OOP试题.docx_第14页
第14页 / 共21页
11级OOP试题.docx_第15页
第15页 / 共21页
11级OOP试题.docx_第16页
第16页 / 共21页
11级OOP试题.docx_第17页
第17页 / 共21页
11级OOP试题.docx_第18页
第18页 / 共21页
11级OOP试题.docx_第19页
第19页 / 共21页
11级OOP试题.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

11级OOP试题.docx

《11级OOP试题.docx》由会员分享,可在线阅读,更多相关《11级OOP试题.docx(21页珍藏版)》请在冰点文库上搜索。

11级OOP试题.docx

11级OOP试题

上海大学2012~2013学年度秋季学期试卷

课程名:

面向对象程序设计课程号:

08305121学分:

5

应试人声明:

我保证遵守《上海大学学生手册》中的《上海大学考场规则》,如有考试违纪、作弊行为,愿意接受《上海大学学生考试违纪、作弊行为界定及处分规定》的纪律处分。

应试人应试人学号应试人所在院系

题号

一(20)

二(30)

三(26)

四(24)

得分

——————————————————————————————————————

一、判断题(每小题2分,共20分)

1.任何类都一定有默认的构造函数(即调用时无须实参的构造函数)。

(×)

2.任何类都至少有一个赋值运算符函数。

(√)

3.执行赋值运算时由系统自动调用复制构造函数。

(×)

4.对象的空间通常由其基本空间和资源空间构成。

(√)

5.类的静态数据成员占用具体对象的存储空间。

(×)

6.类的成员函数对同类的所有对象的所有数据成员有无限制的访问能力。

(√)

7.设函数f是类A的友元函数,类A是类B的友类,此时函数f却不一定是

类B的友元函数。

(√)

8.基类中的私有成员(访问属性为private)在派生类中不可直接访问,须

通过基类的非私有成员函数进行访问。

(√)

9.设有类classA;有指针变量A*p;,语句p=newA;或语句

p=(A*)calloc(1,sizeof(A));都将引起类A的默认构造函数调用。

(×)

10.类的构造函数、析构函数都可以为虚函数。

(×)

 

二、填空及简答(填空20分、简答题10分,共30分)如下矩阵类的设计。

(1)请根据如下程序及其运行结果填空(每空2分)。

#include

#include//为了控制I/O的格式

usingnamespacestd;

templateclassMatrix

{

protected:

introw,col;

T*x;

public:

Matrix(intRow=0,intCol=0,constT*mat=NULL)

:

row(Row),col(Col),x(②NULL)

{

if(Row<=0||Col<=0)

row=col=0;

else

{

x=newT[row*col];

for(inti=row*col-1;i>=0;i--)

x[i]=(mat!

=NULL)?

mat[i]:

T(0);

}

}

Matrix(constMatrix&mat):

x(NULL)

{

*this=mat;

}

virtual~Matrix()

{

if(x!

=NULL)③delete[]x;

}

Matrix&operator=(constMatrix&mat)

{

if(④&mat==this)return*this;

if(x!

=NULL)delete[]x;

row=mat.row;

col=⑤mat.col;

if(row<=0||col<=0)

{

row=col=0;

x=NULL;

}

else

{

x=newT[⑥row*col];

for(inti=row*col-1;i>=0;i--)

x[i]=mat.x[i];

}

return⑦*this;

}

intRow()const{returnrow;}

intCol()const{returncol;}

⑧friendostream&operator<<(ostream&out,constMatrix&mat)

{

for(inti=0;i

{

out<<'[';

for(intj=0;j

out<

out<<']'<

}

return⑨out;

}

T*operator[](intindex)

{

returnx+index*col;

}

};

intmain()

{

Matrixa(3,4);

Matrix<⑩char>c(2,5,"HelloWorld");

运行结果

[Hello]

[World]

[0000]

[0000]

[0000]

[0123]

[1234]

[2345]

cout<

cout<

for(inti=0;i

{

for(intj=0;j

a[i][j]=i+j;

}

cout<

return0;

}

(2)请根据上述程序简要回答问题。

(2.1)(3分)复制构造函数中为什么首先要将指针x初始化为NULL?

与其后执行的语句有什么关系?

复制构造函数体中使用了赋值运算符函数,而赋值运算符函数中若x不为NULL,则执行delete[]操作。

若不将x初始化为NULL,其值可能不可预知,且可能不为NULL,直接执行delete[]将出错。

(2.2)(3分)为什么将运算符函数operator<<重载为友元函数?

因为运算符函数operator<<为双目运算,且第一个操作数不是本类的对象,不能将其定义为成员函数,而将其定义成类的友元函数。

(2.3)(4分)在主函数测试时,为什么可以使用双方括号(如a[i][j]),请分别解释其中第一个方括号、第二个方括号的理由。

表达式a[i][j]中,第一个方括号为该类重载的方括号运算符函数,它返回所谓的“行地址”的地址值;第二个方括号为系统提供的根据地址访问目标变量运算。

三、阅读程序写出运行结果及修改函数(共26分)

(1)有如下头文件Complex.h,其中设计了一个复数类

#ifndefCOMPLEX_H//Complex.h头文件

#defineCOMPLEX_H

#include

usingnamespacestd;

classComplex

{

private:

doublere,im;//复数的实部、虚部

public:

Complex(doublereal=0,doubleimag=0):

re(real),im(imag){}

doubleReal()const{returnre;}

doubleImag()const{returnim;}

voidSet(doublereal,doubleimag){re=real;im=imag;}

friendostream&operator<<(ostream&out,constComplex&c)

{

out<<"("<

returnout;

}

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

{

doublereal,imag;

charstr[100];

in.getline(str,100,'(');//读到左圆括号为止

in.getline(str,100,',');//读到逗号为止

real=atof(str);//将C-字符串转换成浮点数

in.getline(str,100,')');//读到右圆括号为止

imag=atof(str);//将C-字符串转换成浮点数

c.Set(real,imag);//设置复数

returnin;

}

Complexoperator+(constComplex&c)

{

Complextemp;

temp.re=re+c.re;

temp.im=im+c.im;

returntemp;

}

Complex&operator++()

{

re++;//复数增1(仅实部增1)

return*this;

}

Complexoperator++(int)

{

Complextemp(*this);

re++;

returntemp;

}

Complex&operator*=(constComplex&c)

{

Complextemp(*this);

re=temp.re*c.re-temp.im*c.im;

im=temp.re*c.im+temp.im*c.re;

运行结果(1.1)

(0,0)(2,0)(2,3)

(4,3)

(4,0)

(-5,-9)

return*this;

}

};

#endif

(1.1)(4分)请指出下面的程序的运行结果

#include"Complex.h"

intmain()

{

Complexc1,c2=2,c3(2,3);

cout<

c1=c2+c3;

c2*=c2;//请严格按上述operator*=函数计算

c3*=c3;//请注意(2+3i)(2+3i)=-5+12i并不等于-5-9i

cout<

cout<

cout<

return0;

}

(1.2)(4分)从上述运行结果可见,重载运算符*=函数的定义中存在计算错误,请改正。

由此可见重载双目运算符时,需要特别注意两个操作数为同一对象时的情形。

Complex&operator*=(constComplex&c)

{

Complextemp;

temp.re=re*c.re-im*c.im;

temp.im=re*c.im+im*c.re;

*this=temp;

return*this;

}

(1.3)(4分)请指出下面的程序的运行结果

#include"Complex.h"

intmain()

{

Complexc(2,3),d(c);

运行结果(1.3)

(3,3)(3,3)

(2,3)(3,3)

(4,3)(4,3)

(2,3)(3,3)

cout<<++c<<'\t';//此处无换行

cout<

cout<

cout<

c.Set(2,3);

d.Set(2,3);

cout<<++++c<<'\t';//此处无换行

cout<

cout<

cout<

return0;

}

(1.4)(4分)请指出下面的程序的运行结果

#include"Complex.h"

intmain()

运行结果(1.4)

(2,3)

(2,3)

(4,5)

(2,3)

{

Complexc1,c2(2,3),*p;

cout<<(c1=c2)<

cout<

p=newComplex(4,5);

cout<<*p<

deletep;

p=&c1;

cout<<*p<

return0;

}

(2)有如下程序

#include

usingnamespacestd;

classBase

{

protected:

intx,y;

public:

Base(inta,intb=1):

x(a),y(b){}

virtual~Base(){}

virtualvoidShow(ostream&out)const=0;

};

ostream&operator<<(ostream&out,constBase&b)

{

b.Show(out);

returnout;

}

classDerived:

publicBase

{

private:

intz;

public:

Derived(inta,intb,intc):

Base(a,b),z(c){}

Derived&operator+=(constDerived&d)

{

x+=d.x;

y+=d.y;

z+=d.z;

return*this;

}

voidShow(ostream&out)const

{

out<<"[("<

}

};

classRationalNumber:

publicBase//派生有理数类

{

public:

RationalNumber(inta,intb=1):

Base(a,b){}

RationalNumber&operator+=(constRationalNumber&r)

{//有理数(分数)相加

inttemp=x*r.y+y*r.x;

y*=r.y;

x=temp;

return*this;

}

voidShow(ostream&out)const

{

out<

}

};

运行结果

[(3,2),1]

[(4,5),6]

[(7,7),7]

3/2

2/3

13/6

intmain()

{

Derivedd1(3,2,1),d2(4,5,6);

RationalNumberr1(3,2),r2(2,3);

cout<

cout<

d1+=d2;

cout<

cout<

cout<

r1+=r2;

cout<

return0;

}

(2.1)(6分)请指出上述程序的运行结果(填入上面的表格中)。

(2.2)(2分)简要回答。

基类Base中有纯虚函数,故Base为抽象类。

不能创建Base类的对象。

能否声明Base类的引用(例如用派生类的对象初始化引用)?

能否定义目标数据类型为基类的指针变量(例如用派生类对象的地址对其初始化或赋值)?

答:

皆能。

(2.3)(2分)简要回答。

派生类Derived或RationalNumber类的构造函数中为什么要显式地使用冒号语法规则对基类的数据成员进行初始化。

答:

因为基类Base没有默认的构造函数。

四、设计类(每个函数4分,共24分)一个IPv4(InternetProtocolversion4)地址用一个32位(即unsignedlong型)整数表示。

常用点分十进制(dotted-decimalnotation)的形式,即其4个字节被分开用十进制写出,中间用点分隔。

例如某IPv4地址的点分十进制表示为192.168.100.1,则其对应的32位整数为(c0a86401)16即3232261121=((192*256+168)*256+100)*256+1。

请完成如下的成员函数或友元函数的定义,使程序输出指定的结果。

#include

#include

usingnamespacestd;

classIPv4

{

private:

inta,b,c,d;//利用4个整数记录被点分的数

public:

IPv4(char*ip="127.0.0.1")//构造函数

{

inti;

a=b=c=d=0;

for(i=0;ip[i]!

='.';i++)

if(ip[i]>='0'&&ip[i]<='9')

a=10*a+ip[i]-'0';

for(i++;ip[i]!

='.';i++)//请注意此处<表达式1>为i++

if(ip[i]>='0'&&ip[i]<='9')

b=10*b+ip[i]-'0';

for(i++;ip[i]!

='.';i++)

if(ip[i]>='0'&&ip[i]<='9')

c=10*c+ip[i]-'0';

for(i++;ip[i]!

='\0';i++)

if(ip[i]>='0'&&ip[i]<='9')

d=10*d+ip[i]-'0';

}

int&operator[](intk)//重载方括号运算符,可返回各点分部分

{

switch(k)

{

case0:

returna;

case1:

returnb;

case2:

returnc;

default:

returnd;

}

}

friendbooloperator>(constIPv4&ip1,constIPv4&ip2)

{returnip1.get()>ip2.get();}//get函数见后

friendbooloperator>=(constIPv4&ip1,constIPv4&ip2)

{returnip1.get()>=ip2.get();}

friendbooloperator<(constIPv4&ip1,constIPv4&ip2)

{returnip1.get()

friendbooloperator<=(constIPv4&ip1,constIPv4&ip2)

{returnip1.get()<=ip2.get();}

friendbooloperator==(constIPv4&ip1,constIPv4&ip2)

{returnip1.get()==ip2.get();}

friendbooloperator!

=(constIPv4&ip1,constIPv4&ip2)

{returnip1.get()!

=ip2.get();}

IPv4&operator--()//重载前减量运算符

{

d--;

if(d==-1){d=255;c--;}

if(c==-1){c=255;b--;}

if(b==-1){b=255;a--;}

if(a==-1){a=255;}

return*this;

}

IPv4operator--(int)//重载后减量运算符

{

IPv4temp(*this);

--(*this);

returntemp;

}

IPv4operator+(intn)//重载加号运算符,实现IP地址与整数相加

{

IPv4temp;

temp.set(get()+n);

returntemp;

}

IPv4&operator+=(intn)//IPv4对象与整数迭代相加

{

*this=*this+n;

return*this;

}

IPv4operator-(intn)//重载减号运算符,实现IP地址与整数相减

{

return*this+(-n);

}

IPv4&operator-=(intn)//IPv4对象与整数迭代相减

{

*this=*this+(-n);

return*this;

}

intoperator-(constIPv4&ip)//两个IPv4对象相减

{

returnget()-ip.get();

}

//请根据要求定义成员函数或友元函数(请注意:

这是在类体中)。

//①请定义如下函数,返回由a,b,c,d构成的一个32位的无符号长整型数值,

//该函数是前面诸多成员函数的基础。

unsignedlongget()const

{

unsignedlongintn;

n=d+256*(c+256*(b+256UL*a));

returnn;

}

//②请定义如下函数,根据给定的32位无符号长整型数值设置数据成员a,b,c,d。

voidset(unsignedlongn)

{

d=n%256;

c=n/256%256;

b=n/256/256%256;

a=n/256/256/256%256;

}

//③请重载前增量运算符(++)使其为下一个IP(参见测试程序及运行结果)

IPv4&operat

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2