第11章运算符重载 习题解答.docx
《第11章运算符重载 习题解答.docx》由会员分享,可在线阅读,更多相关《第11章运算符重载 习题解答.docx(26页珍藏版)》请在冰豆网上搜索。
![第11章运算符重载 习题解答.docx](https://file1.bdocx.com/fileroot1/2022-11/26/c11d5f1c-3a57-401b-b390-a67c6598c80a/c11d5f1c-3a57-401b-b390-a67c6598c80a1.gif)
第11章运算符重载习题解答
第11章运算符重载
一.单项选择题
1.下列运算符中,运算符在C++中不能重载。
A.?
:
B.+C.D.<=
解:
C++中不能被重载的运算符有:
·,一,:
:
,?
:
。
本题答案为A。
2.下列运算符中,运算符在C++中不能重载。
A.&&B.[]C.:
:
D.new
解:
c++中不能被重载的运算符有:
·,·+,:
:
,?
:
。
本题答案为c。
3.下列关于运算符重载的描述中,是正确的。
A.运算符重载可以改变操作数的个数
B.运算符重载可以改变优先级
C.运算符重载可以改变结合性
D.运算符重载不可以改变语法结构
解:
运算符重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算程的语法结构。
本题答案为D。
4.友元运算符objl>obj2被C++编译器解释为。
A.operator>(objl,obj2)B.>(obj1,obj2)
C.obj2.operator:
>(obj1)D.objl.operator>(obj2)
解:
重载为友元函数的运算符的调用形式如下:
operator<运算符>(<参数1>,<参数2>)
等价于:
<参数1><运算符><参数2>
本题答案为A。
5.现需要对list类对象使用的逻辑运算符“==”重载,以下函数声明是正确的。
A、list&list:
:
operator==(constlist&a);
B、listlist:
:
operator==(constlist&a);
C、bool&list:
:
operator==(constlist&a);
D、boollist:
:
operator==(constlist&a);
6.以下类中分别说明了“+=”和“++”运算符重载函数的原型。
如果主函数中有定义:
funm,c,d;,那么,执行语句c=m++;时,编译器把m++解释为:
(33)
A)c.operator++(m);B)m=operator++(m);
C)m.operator++(m);D)operator++(m);
classfun
{public:
......
funoperator+=(fun);
friendfunoperator++(fun&,int);
};
答案:
D
7.在第33题中,当执行语句d+=m;时,C++编译器对语句作如下解释:
(34)
A.d=operator+=(m);B.m=operator+=(d);
C.d.operator+=(m);D.m.operator+=(d);
答案:
C
8.设有以下类定义,其中说明了“+”运算符重载函数的原型。
这是一个友元函数,当类外有语句a=b+c;访问这个友元函数时,C++编译器把对语句a=b+c;解释为:
operator+(b,c)
其中:
(35)
A.a,b,c都必须是Com的对象B.a,b都必须是Com的对象
C.a,c都必须是Com的对象D.b,c都必须是Com的对象
classCom
{......
friendComoperator+(......);
};
答案:
B
二.填空题
1.利用成员函数对双目运算符重载,其左操作数为,右操作数为。
解:
将双目运算符重载为类的成员函数时,由于this指针在每次非静态成员函数操作对象时都作为第一个隐式参数传递给对象,因此它充当了双目运算符的左操作数,而该成员函数的形参则表示双目运算符的右操作数。
本题答案为:
this指针成员函数参数。
2.运算符重载仍然保持其原来的优先级、和。
解:
运算符重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算符的语法结构。
本题答案为:
结合性语法结构。
3.为了满足运算符“+”的可交换性,必须将其重载为。
解:
以友元函数方式重载运算符可满足运算符“+”的可交换性,因为两个操作数都作为参数,例如,有以下程序:
#include
classSample
{
intn;
public:
Sample(){}
Sample(inti){n=i;}
friendSampleoperator+(Sample,Sample);
voiddisp(){cout<<“n=”<}
Sampleoperator+(samples1,Samples2)
{
returnsample(S1.n+s2.n);
}
voidmain()
{
SampleS1
(2),s2(5),s3;
cout<<”S1:
”;S1.disp();
cout<<”s2:
”;s2.disp();
s3=S1+S2;
cout<<”s3:
”;s3.disp();
S3=S2+S1;
cout<<”s3:
”;s3.disp();
}
程序执行结果如下:
从中看到,执行sl+s2和s2+sl的结果是相同的,从而满足运算符“+”的交换性。
所以本题答案为:
友元函数。
4.在c++中,运算符的重载有两种实现方法,一种是通过成员函数来实现,另一种则通过(4)来实现。
答案:
友元
5.当用成员函数重载双目运算符时,运算符的左操作数必定是:
(5)
答案:
对象
三.程序分析题
1.以下程序的执行结果是。
#include
classSample
{
intn;
public:
Sample(){)
Sample(intm){n=m;)
int&operator--(int)
{
n--;
returnn;
}
voiddisp(){cout<<”rl=”<}
voidmain()
{
Samples(10);
(S--)++;
S.disp();
}
解:
该程序中,类Sample的重载”一”运算符的成员函数返回Sample对象的私有数据成员n的引用。
在main()函数中执行(s--)++;语句时,先调用重载成员函数,使S对象的n值减1,这时返回的是S对象的n的引用,再执行++运算,也就是对s对象的n值执行++运算,所以s对象的11值保持不变。
程序的执行结果为:
n=lO。
2.以下程序的执行结果是:
#include
classSample
{
private:
intx;
public:
Sample(){x=0;}
voiddisp(){cout<<”x=”<void0perator++(){x+=10;}
}
voidmain()
{
Sampleobj;
obj.disp();
obj++;
cout<<“执行。
bj++之后”<obj.disp();
}
解:
在类Sample中设计运算符重载成员函数,使运算符“++”作为于Sample类对象时,该对象的x增10。
本题答案为:
x=0
执行obj++之后
x=10
3.阅读下面的程序,在空白处填写出程序运行后的结果。
#include
classcomplex
{
floatreal,imag,
public:
complex(floatr,floati){real=r;imag=i;}
complex(){real=O;imag=O;}
voidprint();
friendcomplexoperator+(complexa,complexb);
friendcomplexoperator一(complexa,complexb);
friendcomplexoperator‘(complexa,complexb);
friendcomplexoperator/(complexa,complexb);
}
voidcomplex:
:
print()
{
cout<if(imag>O)cout<<”+”;
if(imag!
:
0)cout<}
complexoperator+(complexa,complexb)
{
complextemp;
temp.real=a.real+b.real;
temp.imag=a.imag+b.imag;
returntemp;
}
complexoperator-(complexa,complexb)
{
complextemp;
temp.real=a.real-b.real;
temp.imag=a.imag-b.imag;
returntemp;
}
complexoperator*(complexa,complexb)
{
complextemp;
temp.real:
a.real*b.real-a.imag*b.imag;
temp.imag=a.real*b.imag+a.imag*b.real;
returntemp;
}
complexoperator/(complexa,complexb)
{
complextemp;
floattt;
tt=l/(b.real‘b.real+b.imag。
b.imag);
temp.real=(a.real*b.real+a.imag*b.imag)*tt;
temp.imag=(b.real*a.imag-a.real*b.imag)*tt;
returntemp;
}
voidmain()
{
complexc1(2.3,4.6),c2(3.6,2.8),c3;
c1.print();
c2.print();
c3=c1+c2;
c3.print();
c3=c1-c2;
c3.print();
c3=c1*c2;
c3.print();
c3=c1/c2;
c3.print();
}
程序运行结果为:
2.3+4.6i
3.6+2.8i
(1)
(2)
(3)
(4)
解:
(1)、
(2)、(3)和(4)分别是2.3+4.6i和3.6+2.8i两个复数相加、相减、相乘和相除的结果。
本题答案为:
(1)5.9+7.4i
(2)-1.3+1.8i(3)-4.6+23i;(4)A.1.01731+0.486538i。
四.简答题
1.说明以下类date的功能,并给出程序执行结果。
#include
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31);
c1assdate
{
intmo,rda,ryr;
public:
date(intm,intd,inty){mo=m;da=d;yr=y;}
date(){}
voiddisp(){cout<frienddateoperator+(date&d,intday)//运算符重载友元函数
{
datedt;
dt.mo=d.mo;
dt.yr=d.yr;
day+=d.da;
while(day>dys[dt.mo-1])
{
day-=dys[dt.mo-1];
if(++dt.mo==13)
{
dt.mo=1;
dt.yr++;
}
}
dt.da=day;.
returndt;
}
}
voidmain()
{
datedl(2,10,2003),d2;
d2=dl+365;
d2.disp();
}
解:
类date含有mo、da和),r3个私有数据成员,分别存放一个日期的月份、日号和年份。
其成员函数有:
两个构造函数,disp0成员函数用于显示日期,“+”运算符重载为计算指定日期加上指定天数后的日期。
本程序输出2003年2月10日加上365天后的日期,结果为:
2/10/2004。
2.说明以下类Words的功能,并给出程序执行结果。
#include
#include
classWords
{
char*str;
public:
Words(char*s)
{
str=newchar[strlen(s)+1];
strcpy(str,s);
}
voiddisp(){cout<charoperator[](inti)
{
if(str[i]>=’A’&&str[i]<='Z')//大写字母
returnchar(str[i]+32);
elseif(str[i]>='a'&&str[i]<='z')//4'写字母
returnchar(str[i]-32);
else//其他字符
returnstr[i];
}
}
voidmain()
{
inti;
char*s=”Hello”;
Wordsword(s);
word.disp();
for(i=0;icout<cout<}
解:
Words类含有一个私有数据,其成员函数有:
一个构造函数,disp()函数用于输出str,下标运算符重载函数用于将指定下标的字母大小写互换,其他字符时不变。
本程序的输出结果如下:
Hell()
heLL()
3.有以下两个程序,分析它们的执行结果有什么不同。
程序l:
#include
classPoint
{
intx,y;
public:
Point(){x=y=0;}
Point(inti,intj){x=i;y=j;}
Pointoperator+(Point);
voiddisp()(cout<<”(”<}
PointPoint:
:
operator+(PointP)
{
this->x+=P.x;this->y+=p.y;
return*this;
}
voidmain()
{
Pointpl(2,3),p2(3,4),p3;
cout<<”pl:
”;p1.disp();
cout<<”p2:
”;p2.disp();
p3=pl+p2;
cout<<”执行p3=pl+p2后”<cout<<”pl:
”,p1.disp();
cout<<”p2:
”;p2.disp();
cout<<”p3:
”;p3.disp();
}
程序2:
#include
classPoint{
intx,Y;
public:
Point(){x=y=O;}
Point(inti,intj){x=i,y=j;}
Pointoperator+(Point);
voiddispf){cout<<”(”<}
PointPoint:
:
operator+(PointP)
{
Points;
s.x=x+p.x;s.y=y+p.y;
returns;
}
voidmain()
{
Pointpl(2,3),p2(3,4),p3;
cout<<”pl:
”;p1.disp();
cout<<”p2:
”;p2.disp();
p3=pl+p2;
cout<<”执行p3=pl+p2后”<cout<<”pl:
”;p1.disp();
cout<<”p2:
”;p2.disp();
cout<<”p3:
”;p3.disp();
}
解:
这两个程序中的main函数完全相同,类Point中的运算符重载均采用成员函数方式实现,只是程序l的运算符重载函数使用this指针,而程序2的运算符重载函数使用局部对象。
p3=pl+p2等价于p3=p1.operator+(p2)。
对于程序l,this指针指向p1对象,执行this->x+=p.x;this->y十一p.y;语句,修改pl对象的x和y成员值,执行return*this;语句,将pl对象赋给p3。
所以p1和p3两个对象的x、Y值相同,即p3=pl+p2等价于p1=p1+p2,p3:
pl,其运行结果如下:
pl:
(2,3)
p2:
(3,4)
执行p3=pl+p2后
P1:
(5,7)
p2:
(3,4)
P3:
(5,7)
对于程序2,执行运算符重载函数,Points;语句定义一个对象,s.x=x+p.x;s.y=y+p.y;语句用于修改s对象的x、Y值,ret%il~ls;语句返回该对象,赋给p3,而pl和p2对象不改变。
其运行结果如下:
pl:
(2,3)
p2:
(3,4)
执行p3=pl+p2后
pl:
(2,3)
p2:
(3,4)
p3:
(5,7)
五.完善程序题
1.本程序调用构造函数实现字符串对象的初始化。
调用重载运算符”+”把两个字符串拼接,并通过重载运算符“>”来实现字符串的比较运算。
#include
#include
classstring
{char*str;
public:
string(char*s=0)
{
if(_(14)_){str=newchar[strlen(s)+1];strcpy(__(15)__);}
elsestr=0;
}
friendstringoperator+(string&,string&);
intoperator>(string&);
voidshow(){if(str)cout<};
stringoperator+(string&s1,string&s2)
{
stringt;
t.str=____(16)_____;
strcat(t.str,s2.str);
______(17)_______;
}
intstring:
:
operator>(string&s)
{
if(strcmp(____(18)_____)>0)return1;
elsereturn0;
}
voidmain(void)
{
strings1("southeastuniversity"),s2("mechanicaldepartment");
strings3;s3=s1+s2;
s1.show();s2.show();s3.show();
cout<<(s1>s2)<<'\n';
}
答案:
(14)s(15)str,s(16)s1.str
(17)returnt(18)str,s.str
六.上机题
(一)改错题
(二)编程题
1.定义一个计数器类Counter,对其重载运算符“+”。
解:
计数器类Counter含有一个私有整型数据成员n,“+”运算符重载为使对象的n值增l。
程序如下:
#include
classCounter
{
intn;
public:
Counter(){n=O;}//默认构造函数
Counter(inti){n=i;}//构造函数
Counteroperator+(Counterc)//运算符重载函数
{
Countertemp;
temp.n=n+c.n;
returntemp;
}
voiddisp(){cout<<”n=”<}
voidmain()
{
Countercl(5),c2(10),c3;
c3=c1+c2;
c1.disp();
c2.disp();
c3.disp();
}
2.C++在运行期间不会自动检查数组是否越界。
设计一个类能够检查数组是否越界。
解:
设计一个类Words,下标运算符重载为:
判断指定的下标是否越界,越界时显示相应的错误信息,未越界时返回该下标的字符。
程序如下:
#include
#inc]ude
classWords
{
intlen;//str所指字符串的长度
char*str;//字符串指针
public:
Words(char*s)//构造函数
{
str=newchar[strlen(s)+1];
strcpy(str,s);
len=strlen(s);
}
charoperator[](intn)
{
if(n>len-1)
{
cout<<”数组下标越界”;
return‘’;//返回一个特殊字符
}
else
return*(str+n);
}
voiddisp(){cout<}
voidmain()
{
Wordsword(”Goodbye”);
word.disp();
cout<<”位置0:
”;
cout<cout<<”位置15:
”;
cout<}
3.设计一个日期类Date,包括年、月、日等私有数据成员。
要求实现日期的基本运算,如某日期加上天数、某日期减去天数、两日期相差的天数等。
解:
在Date类中设计如下重载运算符函数:
Dateoperator+(intdays):
返回某日期加上天数得到的日期
Dateoperator~(intdays):
返回某日期减去天数得到的日期
·intoperator-(Date&b):
返回两日期相差的天数
在实现这些重载运算符函数时调用以下私有成员函数:
·leap(int):
判断指定的年份是否为闰年
·dton(Date&):
将指定日期转换成从0年O月O日起的天数
.ntod(int):
将指定的0年O月O日起的天数转换成对应的日期
程序如下:
#include
intday_tab[2][12]={{31,28,31,30,3l,30,3l,3l,30,31,30,31),
{31,29,31,30