int main() {
Complex c1(1,2),c2(3,4);
c1.print();
c2.print();
Complex c3;
c3=c1+c2;
c3.print();
}
程序运行结果为:
Complex class Constructing...
Complex class Constructing...
real:1 imag:2 real:3 imag:4
Complex changed to int...
Complex changed to int...
real:5 imag:5
上例中没有在类中重载运算符“+”,为何 c3=c1+c2 成立呢?原因在于 C++自动进行了隐 式转换,将 c1 与 c2 分别都转换成 int 型,然后调用转换构造函数将整型数据转换为 complex 类。这里类型转换函数和转换构造函数构成了互逆操作,转换构造函数 Complex(int)将一个整 型转换成一个 Complex 类型,而类型转换函数 Complex::operator int()将 Complex 类型转换成 整型。
习题六
一、选择题
1.下列运算符中,_______运算符在 C++中不能被重载。
A. = B.() C.:: D.delete
2.下列运算符中, _______运算符在 C++中不能被重载。
A.?: B.[] C.new D.&&
3.下列关于 C++运算符函数的返回类型的描述中,错误的是_______。
A.可以是类类型 B.可以是 int 类型
C.可以是 void 类型 D.可以是 float 类型 4.下列运算符不能用友元函数重载的是_______。
A.+ B.= C.* D.<<
5.在重载运算符函数时,下面_______运算符必须重载为类成员函数形式。
A.+ B.- C.++ D.->
6.下列关于运算符重载的描述中,正确的是_______。
A.运算符重载可以改变运算符操作数的个数
B.运算符重载可以改变优先级
C.运算符重载可以改变结合性
D.运算符重载不可以改变语法结构
7.友元运算符 obj>obj2 被 C++编译器解释为_______。
A.operator>(obj1,obj2) B.>(obj1,obj2) C.obj2.operator>(obj1) D.obj1.operator>(obj2)
8.在表达式 x+y*z 中,+是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述
中正确的是_______。
A.operator+有两个参数,operator*有两个参数 B.operator+有两个参数,operator*有一个参数 C.operator+有一个参数,operator*有两个参数 D.operator+有一个参数,operator*有一个参数 9.重载赋值操作符时,应声明为_______函数。
A.友元 B.虚 C.成员 D.多态
10.在一个类中可以对一个操作符进行_______重载。
A.1 种 B.2 种以下 C.3 种以下 D.多种
11.在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是_______。
A.作为友元函数重载的单目运算符 B.作为成员函数重载的单目运算符
C.作为友元函数重载的双目运算符 D.作为成员函数重载的双目运算符
12.在成员函数中进行双目运算符重载时,其参数表中应带有_______个参数。
A.0 B.1 C.2 D.3
13.双目运算符重载为普通函数时,其参数表中应带有_______个参数。
A.0 B.1 C.2 D.3
14.如果表达式 a+b 中的“+”是作为成员函数重载的运算符,若采用运算符函数调用格式,则可表示
为_______。
A.a.operator+(b) B.b.operator+(a) C.operator+(a,b) D.operator(a+b)
15.如果表达式 a==b 中的“==”是作为普通函数重载的运算符,若采用运算符函数调用格式,则可表
示为_______。
A.a.operator==(b) B.b.operator==(a) C.operator==(a,b) D.operator==(b,a)
16.如果表达式 a++中的“++”是作为普通函数重载的运算符,若采用运算符函数调用格式,则可表示
为_______。
A.a.operator++() B.operator++(a) C.operator++(a,1) D.operator++(1,a)
17.如果表达式++a 中的“++”是作为成员函数重载的运算符,若采用运算符函数调用格式,则可表示
为_______。
A.a.operator++(1) B.operator++(a) C.operator++(a,1) D.a.operator++()
18.关于运算符重载,下列说法正确的是_______。
A.重载时,运算符的优先级可以改变 B.重载时,运算符的结合性可以改变
C.重载时,运算符的功能可以改变 D.重载时,运算符的操作数个数可以改变
19.关于运算符重载,下列说法正确的是_______。
A.所有的运算符都可以重载
B.通过重载,可以使运算符应用于自定义的数据类型
C.通过重载,可以创造原来没有的运算符
D.通过重载,可以改变运算符的优先级
20.一个程序中数组 a 和变量 k 定义为“int a[5][10],k;”,且程序中包含有语句“a(2,5)=++k*3;”,则此语 句中肯定属于重载操作符的是_______。
A.( ) B.= C.++ D.*
21.假定 K 是一个类名,并有定义“K k; int j;”,已知在 K 中重载了操作符( ),且语句“j=k(3);”和“k(5)=99;”
都能顺利执行,则该操作符函数的原型只可能是_______。
A.K operator( )(int); B.int operator( )(int);
C.int & operator( )(int); D.K & operator( )(int);
22.假定 M 是一个类名,且 M 中重载了操作符“=”,可以实现 M 对象间的连续赋值,如“m1=m2=m3;”。
重载操作符“=”的函数原型最好是_______。
A.int operaotor=(M); B.int operator=(M);
C.M operator=(M); D.M & operator=(M);
23.下面是重载双目运算符“+”的普通函数原型,其中最符合“+”原来含义的是_______。
A.Value operator+(Value, Value); B.Value operator+(Value,int);
C.Value operator+(Value); D.Value operator+(int , Value);
24.下面是重载双目运算符“-”的成员函数原型,其中最符合“-”原来含义的是_______。
A.Value Value::operator-(Value); B.Value Value::operator-(int);
C.Value Value::operator-(Value,int); D.Value Value::operator-(int,Value);
25.在重载运算符时,若运算符函数的形参表中没有参数,则不可能的情况是_______。
A.该运算符是一个单目运算符 B.该运算符函数有一个隐含的参数 this
C.该运算符函数是类的成员函数 D.该运算符函数是类的友元函数
二、填空题
1.不能重载“.”、“::”、“.*”、“->*”和______5 个运算符。
2.运算符重载不能改变运算符的______。
3.在 C++中,运算符的重载有两种实现方法,一种是通过成员函数来实现,另一种则通过______来实现。
4.运算符“--”、“delete”、“-=”、“=”、“+”和“->*”中,只能作为成员运算符重载的有______。
5.运算符“--”、“delete”、“-=”、“=”、“+”和“->*”中,只能重载为静态函数的有______。
6.运算符“--”、“delete”、“-=”、“=”、“+”和“->*”中,肯定不能重载的是______。
7.当运算符重载为成员函数时,对象本身就是______,不在参数表中显式地出现。
8.若以成员函数形式,为类 CSAI 重载“double”运算符,则该运算符重载函数的原型是______。
9.在表达式“x+=y”中,“+=”是作为非成员函数重载的运算符,若是使用显式的函数调用代替直接使
用运算符“+=”,这个表达式还可以表示为______。
10.将运算符“>>”重载为类 CSAI 的友元函数的格式是:friend stream& operator >>______。
三、分析题
1.分析以下程序的执行结果
#include<iostream.h>
class Sample{
int n;
public:
Sample(){}
Sample(int m){n=m;}
int &operator--(int) {
n--;
return n;
}
void disp()
{ cout<<"n="<<n<<endl;}
};
void main() {
Sample s(10);
(s--)++;
s.disp();
}
2.分析以下程序的执行结果
#include<iostream.h>
class Sample{
private:
int x;
public:
Sample(){x=0;}
void disp(){cout<<"x="<<x<<endl;}
void operator++(){x+=10;}
};
void main() {
Sample obj;
obj.disp();
obj++;
cout<<"执行 obj++之后"<<endl;
obj.disp();
}
3.分析以下程序的执行结果
#include<iostream.h>
static int dys[]={31,28,31,30,31,30,31,31,30,31,30,31};
class date{
int mo,da,yr;
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();
}
4.分析以下程序的执行结果
#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') //小写字母 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;
}
5.分析以下程序的执行结果
#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 p1(2,3),p2(3,4),p3;
cout<<"pl:";
p1.disp();
cout<<"p2:";
p2.disp();
p3=p1+p2;
cout<<"执行 p3=pl+p2 后"<<endl;
cout<<"pl:",p1.disp();
cout<<"p2:";
p2.disp();
cout<<"p3:";
p3.disp();
} 四、编程题
1.定义一个计数器类 Counter,对其重载运算符“+”。
2.C++在运行期间不会自动检查数组是否越界,设计一个类来检查数组是否越界。
3.有两个矩阵 a 和 b,均为 2 行 3 列,求两个矩阵之和。重载运算符“+”使之能用于矩阵相加,如:c
= a + b。
4.对于下面的类 MyString,要求重载一些运算符后可以计算表达式 a=b+c,其中 a、b、c 都是类 MyString的对象。请重载相应的运算符并编写测试程序。
class MyString{
public:
MyString(char *s){
str=new char[strlen(s)+1];
strcpy(str,s);
}
~MyString(){delete[]str;}
private:
char *str;
};
5.设计人民币类 RMB,其数据成员为分、角、元,定义构造函数和数据成员 yuan、jiao、fen,重载这 个类的加法、减法运算符。
6.设计一个日期类 Date,包括年、月、日等私有数据成员。要求有实现日期基本运算的成员函数,如
某日期加上天数、某日期减去天数、两日期相差的天数等。
7.定义如下集合类的成员函数,并用数据进行测试。
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(); //输出集合元素 };