第11章 运算符重载 习题解答

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第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==(const list &a);
B、list list::operator==(const list &a);
C、bool & list::operator==(const list &a);
D、bool list::operator==(const list &a);
6. 以下类中分别说明了“+=”和“++”运算符重载函数的原型。

如果主函数中有定义:
fun m,c,d;,那么,执行语句c=m++; 时,编译器把m++解释为: (33)
A) c.operator++(m); B) m=operator++(m);
C) m.operator++(m); D) operator++(m);
class fun
{ public:
.. .. ..
fun operator +=(fun );
friend fun operator ++(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的对象
class Com
{ ... ...
friend Com operator +(... ...);
};
答案:B
二.填空题
1.利用成员函数对双目运算符重载,其左操作数为,右操作数为。

解:将双目运算符重载为类的成员函数时,由于this指针在每次非静态成员函数操作对象时都作为第一个隐式参数传递给对象,因此它充当了双目运算符的左操作数,而该成员函数的形参则表示双目运算符的右操作数。

本题答案为:this指针成员函数参数。

2.运算符重载仍然保持其原来的优先级、和。

解:运算符重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算符的语法结构。

本题答案为:结合性语法结构。

3.为了满足运算符“+”的可交换性,必须将其重载为。

解:以友元函数方式重载运算符可满足运算符“+”的可交换性,因为两个操作数都作为参数,例如,有以下程序:
#include<iostream.h>
class Sample
{
int n;
public:
Sample(){}
Sample(int i){n=i;}
friend Sample operator+(Sample,Sample);
void disp() {cout<<“n=”<<n<<endl; }
}
Sample operator+(sample s1,Sample s2)
{
return sample(S1.n+s2.n);
}
void main()
{
Sample S1(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<iostream.h>
class Sample
{
int n;
public:
Sample(){)
Sample(int m){n=m;)
int &operator--(int)
{
n--;
return n;
}
void disp() { cout<<”rl=”<<n<<endl;)
}
void main()
{
Sample s(10);
(S--)++;
S.disp();
}
解:该程序中,类Sample的重载”一”运算符的成员函数返回Sample对象的私有数据成员n的引用。

在main()函数中执行(s--)++;语句时,先调用重载成员函数,使S对象的n值减1,这时返回的是S对象的n的引用,再执行++运算,也就是对s对象的n值执行++运算,所以s对象的11值保持不变。

程序的执行结果为:n=lO。

2.以下程序的执行结果是:
#include<iostream.h>
class Sample
{
private:
int x;
public:
Sample(){x=0;}
void disp(){cout<<”x=”<<x<<endl;}
void 0perator++(){x+=10;}
}
void main()
{
Sample obj;
obj.disp();
obj++;
cout<<“执行。

bj++之后”<<endl ;
obj.disp();
}
解:在类Sample中设计运算符重载成员函数,使运算符“++”作为于Sample类对象时,该对象的x增10。

本题答案为:
x=0
执行obj++之后
x=10
3.阅读下面的程序,在空白处填写出程序运行后的结果。

#include<iostream.h>
class complex
{
float real,imag,
public:
complex(float r,float i){real=r;imag=i;}
complex(){real=O; imag=O;}
void print();
friend complex operator+(complex a,complex b);
friend complex operator一(complex a,complex b);
friend complex operator‘(complex a,complex b);
friend complex operator/(complex a,complex b);
}
void complex::print()
{
cout<<real:
if(imag>O)cout<<”+”;
if(imag!:0) cout<<imag<<”i”<<endl;
}
complex operator+(complex a,complex b)
{
complex temp;
temp.real=a.real+b.real;
temp.imag=a.imag+b.imag;
return temp;
}
complex operator-(complex a,complex b)
{
complex temp ;
temp.real=a.real-b.real;
temp.imag=a.imag-b.imag;
return temp;
}
complex operator *(complex a,complex b)
{
complex temp;
temp.real:a.real*b.real-a.imag *b.imag;
temp.imag=a.real *b.imag+a.imag *b.real;
return temp;
}
complex operator/(complex a,complex b)
{
complex temp;
float tt;
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;
return temp;
}
void main()
{
complex c1(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<iostream.h>
static int dys[]={31,28,31,30,31,30,31,31,30,31,30,31);
c1ass date
{
int mo ,rda, ryr;
public:
date(int m,int d,int y){mo=m;da=d;yr=y;}
date(){}
void disp(){cout<<mo<< ”/”<<da<<“/”<<yr<<endl;}
friend date operator+(date &d,int day) // 运算符重载友元函数
{
date dt;
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;.
return dt;
}
}
void main()
{
date dl(2,10,2003),d2;
d2=dl+365;
d2.disp();
}
解:类date含有mo、da和),r 3个私有数据成员,分别存放一个日期的月份、日号和年份。

其成员函数有:两个构造函数,disp0成员函数用于显示日期,“+”运算符重载为计算指定日期加上指定天数后的日期。

本程序输出2003年2月10日加上365天后的日期,结果为:2/10/2004。

2.说明以下类Words的功能,并给出程序执行结果。

#include<iostream.h>
#include<string.h>
class Words
{
char *str;
public:
Words(char *s)
{
str=new char[strlen(s)+1];
strcpy(str,s);
}
void disp(){cout<<str<<endl;}
char operator[](int i)
{
if(str[i]>=’A’&& str[i]<='Z') // 大写字母
return char(str[i]+32);
else if(str[i]>='a'&&str[i]<='z') // 4'写字母
return char(str[i]-32);
else // 其他字符
return str[i];
}
}
void main()
{
int i;
char *s=”Hello”;
Words word(s);
word.disp();
for(i=0;i<strlen(s);i++)
cout<<word[i];
cout<<endl:
}
解:Words类含有一个私有数据,其成员函数有:一个构造函数,disp()函数用于输出str,下标运算符重载函数用于将指定下标的字母大小写互换,其他字符时不变。

本程序的输出结果如下:
Hell()
heLL()
3.有以下两个程序,分析它们的执行结果有什么不同。

程序l:
#include<iostream.h>
class Point
{
int x,y;
public:
Point(){x=y=0;}
Point(int i,int j){x=i;y=j;}
Point operator+(Point);
void disp() ( cout<<”(”<<x<<”,”<<y<<”)”<<endl; ) }
Point Point::operator+(Point P)
{
this->x+=P.x; this->y+=p.y;
return *this;
}
void main()
{
Point pl(2,3),p2(3,4),p3;
cout<<”pl:”;p1.disp();
cout<<”p2:”;p2.disp();
p3=pl+p2;
cout<<”执行p3=pl+p2后”<<endl;
cout<<”pl:”,p1.disp();
cout<<”p2:”;p2.disp();
cout<<”p3:”;p3.disp();
}
程序2:
#include<i0Stream.h>
class Point{
int x,Y;
public:
Point(){x=y=O;}
Point(int i,int j){x=i,y=j;}
Point operator+(Point);
void disp f){cout<< ”(”<<x<< ”,”<<y<<”)”<<endl; } }
Point Point::operator+(Point P)
{
Point s;
s.x=x+p.x; s.y=y+p.y;
return s;
}
void main()
{
Point pl(2,3),p2(3,4),p3;
cout<<”pl:”;p1.disp();
cout<<”p2:”;p2.disp();
p3=pl+p2;
cout<<”执行p3=pl+p2后”<<endl;
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;语句,修改p l对象的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,执行运算符重载函数,Point s;语句定义一个对象,s.x=x+p.x;s.y=y+p.y;语句用于修改s对象的x、Y值,ret%il~l s;语句返回该对象,赋给p3,而pl和p2对象不改变。

其运行结果如下:
pl:(2,3)
p2:(3,4)
执行p3=pl+p2后
pl:(2,3)
p2:(3,4)
p3:(5,7)
五.完善程序题
1.本程序调用构造函数实现字符串对象的初始化。

调用重载运算符”+”把两个字符串拼接,
并通过重载运算符“>”来实现字符串的比较运算。

#include<iostream.h>
#include<string.h>
class string
{ char *str;
public:
string(char *s=0)
{
if(_(14)_){str=new char[strlen(s)+1]; strcpy(__(15)__);}
else str=0;
}
friend string operator+(string &,string &);
int operator>(string &);
void show(){ if(str)cout<<str<<'\n'; }
};
string operator+(string &s1,string &s2)
{
string t;
t.str=____(16)_____;
strcat(t.str,s2.str);
______(17)_______;
}
int string::operator>(string &s)
{
if(strcmp(____(18)_____)>0)return 1;
else return 0;
}
void main(void)
{
string s1("southeast university"),s2("mechanical department");
string s3; s3=s1+s2;
s1.show(); s2.show(); s3.show();
cout<<(s1>s2)<<'\n';
}
答案:(14) s (15) str,s (16) s1.str
(17) return t (18) str,s.str
六.上机题
(一)改错题
(二)编程题
1.定义一个计数器类Counter,对其重载运算符“+”。

解:计数器类Counter含有一个私有整型数据成员n,“+”运算符重载为使对象的n 值增l。

程序如下:
#include<iostream.h>
class Counter
{
int n;
public:
Counter(){n=O;} // 默认构造函数
Counter(int i){n=i;} // 构造函数
Counter operator+(Counter c) // 运算符重载函数
{
Counter temp;
temp.n=n+c.n;
return temp;
}
void disp() { cout<<”n=”<<rl<<endl; }
}
void main()
{
Counter cl(5),c2(10),c3;
c3=c1+c2;
c1.disp();
c2.disp();
c3.disp();
}
2. C++在运行期间不会自动检查数组是否越界。

设计一个类能够检查数组是否越界。

解:设计一个类Words,下标运算符重载为:判断指定的下标是否越界,越界时显示相应的错误信息,未越界时返回该下标的字符。

程序如下:
#include<iostream.h>
#inc]ude<string.h>
class Words
{
int len; // str所指字符串的长度
char *str; // 字符串指针
public:
Words(char *s) // 构造函数
{
str=new char[strlen(s)+1];
strcpy(str,s);
len=strlen(s);
}
char operator[](int n)
{
if(n>len-1)
{
cout<<”数组下标越界”;
return ‘’; // 返回一个特殊字符
}
else
return*(str+n);
}
void disp(){cout<<str<<endl;}
}
void main()
{
Words word(”Goodbye”);
word.disp();
cout<<”位置0:”;
cout<<word[0]<<endl; // 显示’G’
cout<<”位置15:”;
cout<<word[15]<<endl; // 越界
}
3.设计一个日期类Date,包括年、月、日等私有数据成员。

要求实现日期的基本运算,如某日期加上天数、某日期减去天数、两日期相差的天数等。

解:在Date类中设计如下重载运算符函数:
Date operator+(int days):返回某日期加上天数得到的日期
Date operator~(int days):返回某日期减去天数得到的日期
·int operator-(Date&b):返回两日期相差的天数
在实现这些重载运算符函数时调用以下私有成员函数:
·leap(int):判断指定的年份是否为闰年
·dton(Date &):将指定日期转换成从0年O月O日起的天数
.ntod(int):将指定的0年O月O日起的天数转换成对应的日期程序如下:
#include<iostream.h>
int day_tab[2][12]={{31,28,31,30,3l,30,3l,3l,30,31,30,31),
{31,29,31,30,31,30,31,31,30,31,30,31}};
// day_tab二维数组存放各月天数,第一行对应非闰年,第二行对应闰年
class Date
{
int year,month,day; // 年,月,日
int leap(int); // 判断是否为闰年
int dton(Date&);
Date ntod(int);
public:
Date(){}
Date(int Y,int m,int d){ year=y;month=m;day=d;}
void setday(int d){day=d;}
void setmonth(int m){month=m;}
void setyear(int y){year=y;}
int getday(){return day;}
int getmonth(){return month;}
int getyear(){return year;}
Date operator+(int days) // +运算符重载函数
{
static Date date ;
int number=dton(*this)+days;
date=ntod(number);
return date;
}
Date operator-(int days) // 一运算符重载函数
{
Static Date date;
int number=dton( *this);
number-=days;
date=ntod(number);
return date;
}
int operator-(data &b) // 一运算符重载函数
{
int days=dton(*this)-dton(b)-1;
return days;
}
void disp() // 输出日期
{cout<<year<<”.”<<month<<”.”<<day<<endl:}
}
int Date::leap(int year)
{
if(year%4==0 && year%100!=0 || year%400==0)// 是闰年 return 1;
else // 不是闰年
return 0;
}
int Date::dton(Date)&d) // 求从公元0年0月0日到d日期的天数{
int y,m,days=0;
for (y=1;y<=d.year;y++)
if(1eap(y))days+=366; // 闰年时加366天
else days+=365; // 非闰年时加365天
for(m=0;m<d.month-1;m++)
if(leap(d.year))days+=day_tab[1][m];
else days+=day_tab[0][m];
days+=d.day;
return days;
}
Date Date::ntod(int n) // 将从公元0年0月0日的天数转换成日期{
int y=l;m=l;d, rest=n,lp;
while(1)
{
if(leap(y)) // 闰年
if(rest<=366) break;
else rest-=366;
else // IP闰年
if(rest<=365) break;
else rest-=365;
y++;
}
y--;
ip=leap(y);
while(1)
{
if(ip) // 闰年
if(rest>day;tab[1][m-1])rest-=day_tab[1][m-i];
else break;
else // 非闰年
if(rest>day_tab[0][m-1])rest-=day_tab[0][m-1];
else break;
m++:
}
d=rest;
return Date(y,m,d);
}
void mein()
{
Date now(2003,10,1),then(2005,6,5);
cout<<”now:”;now.disp();
cout<<”then:”;then.disp();
cout<<”相差天数:”<<(then—now)<<endl;
Date dl=now+1000,d2=now-i000;
cout<<”now+1000:”;dl.disp();
cout<<”now—1000:”;d2.disp();
}
本程序的执行结果如下:
now:2003.10.1
then:2005.6.5
相差天数:612
now+1000:200 6.6.27
now一1000:2001.1.14
4.定义如下集合类的成员函数,并用数据进行测试。

class Set
{
int *elem; // 存放集合元素的指针
int count ; // 存放集合中的元素个数
public:
Set();
Set(int s[],int n);
int find(int x)const; //判断X是否在集合中 Set operator+(const Set&); //集合的并集Set operator-(const Set&); //集合的差集 Set operator*(const Set&);//集合的交集
void disp(); //输出集合元素
}
解:该类的运算符重载均采用成员函数方式实现。

程序如下:#include<iostream.h>
const int N=100; //集合中最多元素个数
class Set
{
int * elem; //存放集合元素的指针
int count; //存放集合中的元素个数
public:
Set();
Set(int S[],int n);
int find(int x)const; //判断X是否在集合中 Set operator+(const Set&);//集合的并集
Set operator-(const Set&); //集合的差集
Set operator*(const Set&); //集合的交集
void disp(); //输出集合元素
}
Set::Set() //默认构造函数
{
elem=NULL;
count=O;
}
Set::Set(int s[],int n) // 初始化构造函数
{
int i;
elem=new int[n];
for(i=0; i<n; i++)
*(elem+i)=s[i];
count=n;
}
int Set::find(int x)const
{
int i;
for(i=O;i<count;i++)
if(*(elem+i)==x)
return 1;
return 0;
}
Set Set::operator+(const set &s)
{
int a[N],i,k;
for(i=0;i<count;i++) // 先将当前集合元素放入a数组中 a[i]=elem[i];
k=count;
for(i=0;i<s.count;i++) // 将集合s中不在当前集合中的元素放入a
数组中
if(find(s.elem[I]))
continue;
else
{
if(k==N-1)break;
a[k++]=s.elem[i];
}
return Set(a,k); // 调用构造函数产生一个无名对象返回
}
Set Set::operator-(const Set&s) // 集合的差集
{
int a[N],i,k=0;
for(i=0;i<count;i++) // 将当前集合中不在s集合中的元素放入a数
组中
if(!s.find(elem[i]))
a[k++]=elem[i];
return Set(a,k); // 调用构造函数产生一个无名对象返回
}
Set Set::operator*(const Set &s) // 集合的交集
{
int a[N],k=0,i;
for(i=0;i<count;i++) // 扫描当前集合中所有元素
if(s.find(elem[i]))
a[k++]=elem[i]; // 将属于两个集合的元素放在a数组中 return Set(a,k); // 调用构造函数产生一个无名对象返回
}
void Set::disp() // 输出集合元素
{
int i;
for(i=0;i<count;i++)
cout<<*(elem+i)<<””;
cout<<endl:
}
void main()
{
int a[]={1,4,2,7,8};
int b[]={2,3,1,6,7,};
Set s1(a,5),s2(b,5),s3;
cout<<”集合S1:”;s1.disp();
cout<<”集合s2:”; s2.disp();
S3=s1+S2;
cout<<”并集:”;s3.disp();
S3=s1*S2;
cout<<”交集:”;S3.disp();
S3=s1-s2;
cout<<”差集:”;s3.disp()j
}
本程序的执行结果如下:
集合S1:1 4 2 7 8
集合S2:2 3 1 6 7
并集:1 4 2 7 8 3 6
交集:1 2 7
差集:4 8
5.编写一个程序,重载“+”、“-”、“+=”运算符,完成对复数的相应运算。

要求:(1)定义复数类以及相应的重载函数;
(2)在主函数中定义三个复数对象,并初始化其中的两个;
(3)使用初始化过的两个复数,分别进行“+”、“-”和“+=”运算,将运算结果赋给第三个复数,并显示之;
(4)将计算输出的结果以注释的形式符于程序后面;
(5)程序文件名为myfile1.cpp 。

6.学生管理模拟程序(18分)
【要求】按以下描述和要求建立两个类student和manage:
class student{ //学生类,使用缺省构造函数
friend class manage;
private:
int xh; //学号
char *xm; //姓名
float cj; //成绩
public:
student &operator=(student &t); //将t数据成员的值拷贝给this对象(深拷贝) };
class manage{ //学生管理类
private:
student s[30]; //存放学生信息,最多可有30位学生
int n; //实际学生人数
void swap(student &a,student &b); //交换对象a和b的数据成员值
public:
manage(){n=0;} //学生表构造函数
void newstu(int a,char *b,float c); //在数组s中添加一个学生
//(为student类对象的数据成员赋值) void list(); //屏幕打印学生清单
int maxcj(); //找出成绩最高的学生,输出其学号、姓名和成绩,
//返回该学生在数组s中的位置
int minicj(); //找出成绩最低的学生,输出其学号、姓名和成绩,
//返回该学生在数组s中的位置
void select(); //将成绩最高的学生交换到数组s的第一个元素,
//同时将成绩最低的学生交换到s[n-1]
};
void manage::swap(student &a, student &b){ //交换对象a和b
student temp;
temp=a;a=b;b=temp;
}
请完成以上未定义函数体的成员函数。

在主程序中定义一个manage类对象,调用成员函数newstu()向学生表(s数组)中添加若干学生。

调用成员函数list()在屏幕上输出学生信息。

调用成员函数maxcj()找出成绩最高的学生,调用成员函数minicj()找出成绩最低的学生。

调用成员函数select()按要求将成绩最高的学生交换到数组s的第一个元素,同时将成绩最低的学生交换到s[n-1]。

注意实现运算符’=’号的重载。

字符串复制可使用string.h中包含的strcpy( )函数。

每个成员函数至少被使用一次。

通过多次的函数调用来测试你的程序功能是否达到要求。

【注意】将源程序以文件名MYF2.cpp存入Z盘自己的文件夹中。

相关文档
最新文档