第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
class Sample
{
int n;
public:
Sample(){}
Sample(int i){n=i;}
friend Sample operator+(Sample,Sample);
void disp() {cout<<“n=”< } 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 class Sample { int n; public: Sample(){) Sample(int m){n=m;) int &operator--(int) { n--; return n; } void disp() { cout<<”rl=”< } 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 class Sample { private: int x; public: Sample(){x=0;} void disp(){cout<<”x=”< void 0perator++(){x+=10;} } void main() { Sample obj; obj.disp(); obj++; cout<<“执行。bj++之后”< obj.disp(); } 解:在类Sample中设计运算符重载成员函数,使运算符“++”作为于Sample类对象时,该对象的x增10。本题答案为: x=0 执行obj++之后 x=10 3.阅读下面的程序,在空白处填写出程序运行后的结果。 #include 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< if(imag>O)cout<<”+”; if(imag!:0) cout< } 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 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< 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 #include class Words { char *str; public: Words(char *s) { str=new char[strlen(s)+1]; strcpy(str,s); } void disp(){cout< 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 cout< cout< } 解:Words类含有一个私有数据,其成员函数有:一个构造函数,disp()函数用于输出str,下标运算符重载函数用于将指定下标的字母大小写互换,其他字符时不变。本程序的输出结果如下: Hell() heLL() 3.有以下两个程序,分析它们的执行结果有什么不同。 程序l: #include 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<<”(”< 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后”< cout<<”pl:”,p1.disp(); cout<<”p2:”;p2.disp(); cout<<”p3:”;p3.disp(); } 程序2: #include 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<< ”(”< 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后”< 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 #include 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< }; 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 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=”< } void main() { Counter cl(5),c2(10),c3; c3=c1+c2; c1.disp(); c2.disp(); c3.disp(); } 2. C++在运行期间不会自动检查数组是否越界。设计一个类能够检查数组是否越界。 解:设计一个类Words,下标运算符重载为:判断指定的下标是否越界,越界时显示相应的错误信息,未越界时返回该下标的字符。程序如下: #include #inc]ude 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< } void main() { Words word(”Goodbye”); word.disp(); cout<<”位置0:”; cout< cout<<”位置15:”; cout< } 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 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< } 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 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)< 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 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 *(elem+i)=s[i]; count=n; } int Set::find(int x)const { int i; for(i=O;i if(*(elem+i)==x) return 1; return 0; } Set Set::operator+(const set &s) { int a[N],i,k; for(i=0;i k=count; for(i=0;i 数组中 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 组中 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 if(s.find(elem[i])) a[k++]=elem[i]; // 将属于两个集合的元素放在a数组中 return Set(a,k); // 调用构造函数产生一个无名对象返回 } void Set::disp() // 输出集合元素 { int i; for(i=0;i cout<<*(elem+i)<<””; cout< } 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盘自己的文件夹中。 运算符重载基础概念练习题 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.oprator>(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、在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是()。 1.概念填空题 1.1运算符重载是对已有的运算符赋予多重含义,使同一个运算符在作用于不同类型对象时导致不同的行为。运算符重载的实质是函数重载,是类的多态性特征。 1.2可以定义一种特殊的类型转换函数,将类的对象转换成基本数据类型的数据。但是这种类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。类类型转换函数既没有参数,也不显式给出返回类型。类类型函数中必须有return 表达式的语句返回函数值。一个类可以定义多个类类型转换函数。 1.3运算符重载时其函数名由operator运算符构成。成员函数重载双目运算符时,左操作数是对象,右操作数是函数参数。 2.简答题 2.2简述运算符重载的规则。 2.2简述重载单目运算符++、--,前置和后置时的差别。 2.3 C++中重运算符是否都可以重载?是否都可以重载成类的成员函数?是否都可以重载成类的友元函数? 2.4 构造函数作为类型转换函数的条件是什么。 3.选择题 3.1在下列运算符中,不能重载的是(B) A.! B. sizeof C. new D. delete 3.2 不能用友员函数重载的是(A)。 A.= B.== C.<= D.++ 3.3下列函数中,不能重载运算符的函数是(B)。 A.成员函数 B.构造函数 C.普通函数 D.友员函数 3.4如果表达式++i*k时中的”++”和”*”都是重载的友元运算符,则采用运算符函数调用格式,该表达式还可表示为(B)。 A.operator*(i.operator++(),k) B.operator*(operator++(i),k) C.i.operator++().operator*(k) D.k.operator*(operator++(i)) 3.5已知在一个类体中包含如下函数原型:VOLUME operator-(VOLUME)const;下列关于这个函数的叙述中,错误的是(B )。 A.这是运算符-的重载运算符函数 B.这个函数所重载的运算符是一个一元运算符 C.这是一个成员函数 D.这个函数不改变数据成员的值 3.6在表达式x+y*z中,+是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是(C )。 A.operator+有两个参数,operator*有两个参数 B.operator+有两个参数,operator*有一个参数 C.operator+有一个参数,operator*有两个参数 D.operator+有一个参数,operator*有一个参数 4.写出下列程序运行结果 4.1#include 面向对象程序设计综合练习(单选题) 单选题 1.C++源程序文件的缺省扩展名为( )。 A. cpp B. exe C. obj D. lik 2.程序运行中需要从键盘上输入多于一个数据时,各数据之间应使用( )符号作为分 隔符。 A. 空格或逗号 B. 逗号或回车 C. 逗号或分号 D. 空格或回车 3.关于封装,下列说法中不正确的是()。 A. 通过封装,对象的全部属性和操作结合在一起,形成一个整体 B. 通过封装,一个对象的实现细节被尽可能地隐藏起来(不可见) C. 通过封装,每个对象都成为相对独立的实体 D. 通过封装,对象的属性都是不可见的 4.面向对象软件开发中使用的OOA表示()。 A. 面向对象分析 B. 面向对象设计 C. 面向对象语言 D. 面向对象方法 5.面向对象软件开发中使用的OOD表示()。 A. 面向对象分析 B. 面向对象设计 C. 面向对象语言 D. 面向对象方法 6.在一个类的定义中,包含有()成员的定义。 A. 数据 B. 函数 C. 数据和函数 D. 数据或函数 7.在类作用域中能够通过直接使用该类的()成员名进行访问。 A. 私有 B. 公用 C. 保护 D. 任何 8.在关键字public后面定义的成员为类的()成员。 A. 私有 B. 公用 C. 保护 D. 任何 9.在关键字private后面定义的成员为类的()成员。 A. 私有 B. 公用 C. 保护 D. 任何 10.假定AA为一个类,a为该类公有的数据成员,x为该类的一个对象,则访问x对象 中数据成员a的格式为()。 A. x(a) B. x[a] C. x->a D. x.a 11.假定AA为一个类,a()为该类公有的成员函数,x为该类的一个对象,则访问x对象 中成员函数a()的格式为()。 A. x.a B. x.a() C. x->a D. x->a() 12.假定AA为一个类,a为该类公有的数据成员,px为指向该类对象的一个指针,则访 问px所指对象中数据成员a的格式为()。 A. px(a) B. px[a] C. px->a D. px.a 13.假定AA为一个类,a为该类私有的数据成员,GetValue()为该类公有成员函数,它 返回a的值,x为该类的一个对象,则访问x对象中数据成员a的格式为()。 A. x.a B. x.a() C. x->GetValue() D. x.GetValue() 14.假定AA为一个类,int a()为该类的一个成员函数,若该成员函数在类定义体外定 义,则函数头为()。 A. int AA::a() B. int AA:a() C. AA::a() D. AA::int a() 15.假定AA为一个类,a为该类公有的数据成员,若要在该类的一个成员函数中访问它, 走进3D的世界 -- C++中用运算符重载实现矩阵运算 作者:周军 矩阵(Matrix)无处不在,我们的生活中到处都能找到矩阵的身影,然而此处我不想把这个定义放大,我们只讨论线性代数中的矩阵,我们要用它们来完成我们的3D变换。为什么矩阵可以完成3D变换呢?下面,我们就来介绍矩阵是如何变换坐标的: 设空间中有一坐标(x,y,z),如果我们想把它变换成另一坐标(x,’y’,z’),我们可以进行如下操作: = (x’,y’,z’,1) 这就是矩阵的妙用了。它在复杂处理变换的时候表现得尤为突出。假设我们想要把一个物体先沿z轴旋转角thetaZ,再沿x轴旋转角thetaX,我们可以进行如下操作(pseudo-code): obj*=rotX(thetaX)*rotZ(thetaZ); 注意:矩阵的乘法是不可逆的,而且我们要按变化顺序的逆序进行乘法,具体推导见计算几何相关书籍。 下面,我们进入正题:如何再C++中用重载运算符的方法来进行矩阵运算以完成线性变换呢?我们需要变换坐标,所以很自然地,我们需要一个向量(Vector)类;同时我们要进行 为直观、人性化,我选用了运算符重载这以技巧而不是简单地调用函数,下面请看我的具体实现: 以上便是CVector类的具体实现,我想对C++和线性代数有所了解的读者都能很清楚地理解这段代码,在次不累述。 上述代码的成员函数实在类外定义的,如果读者在实践中为了提高速度可以把这些成员函数定义在类内以起到内联函数的作用,可以省去参数压栈、出栈时的时间。 下面是CMatrix类的具体实现: 是不是也很好理解呢?哈哈,这就是用运算符重载的好处。不过这种方法也确实有它的不足,而且这个不足在游戏编程中是致命的,那就是效率不高,这也正是为什么Microsoft 在DirectX中也使用难看的一般函数调用来完成矩阵运算的原因。影响速度的主要原因是在使用运算符+、-、*、/等时,程序会在每次运算时创建临时对象再将临时对象返回,对于重复多次的矩阵运算来说,这无疑成为了一笔庞大的额外开销(好在现在的计算机的处理速度还算快)。但注意:在使用+=、-=、*=、/=时不会有上述问题,因为在使用这些运算符时程序只需要修改第一个对象不需要创建并返回临时对象。所以在能使用+=、-=、*=、/=时尽量不要使用单一的=、-、*、/运算符。 好了,这两个类我们已经封装好了,下面还有什么呢?是的,忘了向大家交代旋转矩阵了: 运算符重载 一.单项选择题 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. 设有以下类定义,其中说明了“+”运算符重载函数的原型。这是一个友元函数,当类 Task8-1 /* 1. 定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和*/ #include /*2. 定义一个复数类Complex,重载运算符“+”、”-“、”*”、”/”, 使之能用于复数的加、减、乘、除。运算符重载函数作为Complex类的成员函数,编程,分别求两个复数之和差积商。 */ #include 运算符重载复习题 1. 重载赋值操作符时,应声明为( ) A. 友元函数 B. 虚函数 C. 成员函数 D. 多态函数 2.关于重载的描述,正确的是( ) A.函数重载只能在成员函数之间进行 B.函数重载只能在全局函数之间进行 C.函数重载可以在基类和派生类之间进行 D.函数重载必须要求同名的函数的形参类型和个数都完全一致,返回值类型无所谓 3.下列运算符中不能重载的是( )。 A.∷(域运算符) B.+ (正) C.++ (自增) D.*(指针) 4. 派生类的对象对它的基类成员中() A. 公有继承的公有成员是可以访问的 B. 公有继承的私有成员是可以访问的 C. 公有继承的保护成员是可以访问的 D. 私有继承的公有成员是可以访问的 5 不能重载的运算符是() A. ?: B. [ ] C. new D. && 6. C++中不能重载的运算符是( ) A. new B. += C. sizeof D. && 7.重载函数是( ) A.以函数参数来区分,而不用函数的返回值来区分不同的函数 B.以函数的返回值来区分,而不用函数参数来区分不同的函数 C.参数表完全相同而返回值类型不同的两个或多个同名函数 D.参数表和返回值类型中至少有一个不同的两个或多个同名函数 8.对于运算符重载,说法正确的是( ) A.运算符如果被重载为非成员函数,那么对象就不能利用这个运算符重载函数进行操作 B.运算符重载函数可能既不是成员函数,也不是友元函数 C.用户每定义一个类,系统会自动提供一个赋值运算符重载函数,所以完全不 必考虑重载赋值运算符函数 D.一个类的虚函数不能调用运算符重载函数 9. C++中不能重载的运算符是( ) 二、运算符重载(运算符重载的基本概念、运算符重载方法、运算符重载规则、特殊运算符重载和类型转换) 单选题10道: 1、假定要对类AB定义加号操作符重载成员函数,实现两个AB类对象的加法,并返回相加结果,则该成员函数的声明语句为( B )。 A. AB operator+(AB& a,AB& b) B. AB operator+(AB& a) C. operator+(AB a) D. AB &operator+( ) 2、关于运算符重载,下面的叙述错误的是()。 A.运算符预定义的操作数个数不能改变 B.重载不能改变运算符的优先级顺序 C.参数的类型没有限制 D.尽量使其与原意保持一致 3、在一个类中可以对一个操作符进行(D )重载。 A. 1种 B. 2种以下 C. 3种以下 D. 多种 4、重载赋值操作符时,应声明为(C )函数。 A. 友元 B. 虚 C. 成员 D. 多态 5、要在类对象使用运算符,以下不必被重载的运算符是( A )。 A. [] B. = C. ++ D. -- 6、下列运算符中,不能重载的是(C ) A.new B.() C.::D.&& 7、在表达式x+y*z中,+ 是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是( A )。 A)operator+有两个参数,operator*有两个参数 B)operator+有两个参数,operator*有一个参数 C)operator+有一个参数,operator*有两个参数 D)operator+有一个参数,operator*有一个参数 8、友元运算符obj1>obj2被C++编译器解释为()。 A) operator>(obj1,obj2) B) >(obj1,obj2) C) obj1.operator>(obj2) D) obj2.operator>(obj1) 9、已知某个类的友元函数重载了+=和-,a,b,c是该类的对象,则“a+=b-c”被C++编译器解释为()。 A) operator+=(a,operator-(b,c)) B) a.operator+=(b.operator-(c)) C) operator+=(a,b.operator-(c)) D) a.operator+=(operator-(b,c)) 10、下列运算符中,必须使用成员函数进行重载的是()。 A) == B) = C) >> D) ++ 填空题10道: 1、多数运算符既能作为类的成员函数重载,也能作为类的非成员函数重载,但运算符“[]”只能作为类的函数重载。 2、加法运算符“+”和赋值运算符“=”都重载之后,“+=”也被重载了。 3、单目运算符作为类的成员函数重载时形参。 4、利用成员函数对二元运算符重载时,其右操作数为。 5、重载运算符函数的函数名由关键字引出。 6、运算符的重载归根结底是的重载。 7、后缀自增自减运算符定义时带有一个。 《面向对象程序设计》习题 班级:学号:姓名:名单序号:成绩: 第7章运算符重载和多态性 一、选择题(共30分,每题1分) 1.下列运算符中,()运算符在C++中不能重载。 A.?: B.[] C. new D.++ 2.友元重载运算符obj1>obj2被C++编译器解释为()。 A.operator >(obj1,obj2) B.>(obj1,obj2) C.obj2.operator >(obj1) D.obj1.operator >(obj2) 3.重载赋值操作符时,应声明为()函数。 A.友元B.虚C.成员D.多态 4.在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是()。 A. 作为友元函数重载的1元运算符 B. 作为成员函数重载的1元运算符 C. 作为友元函数重载的2元运算符 D. 作为成员函数重载的2元运算符5.在重载一运算符时,若运算符函数的形参表中没有参数,则不可能的情况是()。 A. 该运算符是一个单目运算符。 B. 该运算符函数有一个隐含的参数this。 C. 该运算符函数是类的成员函数。 D. 该运算符函数是类的友元函数。 6. 关于运输符重载,下列表述中正确的是()。 A.C++已有的任何运算符都可以重载 B.运算符函数的返回类型不能声明为基本数据类型 C.在类型转换符函数的定义中不需要声明返回类型 D.可以通过运算符重载来创建C++中原来没有的运算符 7. C ++流中重载的运算符>>是一个()。 A. 用于输出操作的非成员函数 B. 用于输出操作的成员函数 C. 用于输入操作的非成员函数 D. 用于输入操作的成员函数 8. 若要对Data类中重载的加法运算符成员函数进行声明,下列选项中正确的是()。 A. Data +(Data); B. Data operator+(Data); C. Data +operator(Data); D. operator +(Data, Data); 9. 下列运算符中哪些是不能够被重载的()。 A. .,.*,sizeof,::,?: B. ++,--,new,= = C. new,delete,>=,[ ] D. +,-,=,delete 10. 在名为BigNumber类的类体中对运算符函数double进行如下声明: operator double(BigNumbe); 函数声明中有一个明显的错误,这个错误就是()。 A.参数表中不应该有任何参数 B.缺少对函数返回类型的说明 C.参数声明中缺少参数变量 D.函数声明中缺少函数体 11. 下列关于运算符重载的描述中,正确的是()。 一、运算符重载的规则 运算符重载规则如下: ①、C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。 ②、重载之后运算符的优先级和结合性都不会改变。 ③、运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 不能重载的运算符只有五个,它们是:成员运算符“.”、指针运算符“*”、作用域运算符“::”、“sizeof”、条件运算符“?:”。 运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。 运算符重载为类的成员函数的一般语法形式为: 函数类型 operator 运算符(形参表) { 函数体; } 运算符重载为类的友元函数的一般语法形式为: friend 函数类型 operator 运算符(形参表) { 函数体; } 其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。 当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;当重载为类的友元函数时,参数个数与原操作数个数相同。原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。而重载为友元函数时,友元函数对某个对象的数据进行操作,就必须通过该对象的名称来进行,因此使用到的参数都要进行传递,操作数的个数就不会有变化。 运算符重载的主要优点就是允许改变使用于系统内部的运算符的操作方式,以适应用户自定义类型的类似运算。 一般说来,单目运算符最好被重载为成员;对双目运算符最好被重载为友元函数,双目运算符重载为友元函数比重载为成员函数更方便此,但是,有的双目运算符还是重载为成员函数为好,例如,赋值运算符。 二、运算符重载为成员函数 对于双目运算符B,如果要重载B为类的成员函数,使之能够实现表达式oprd1 B oprd2,其中oprd1为类A的对象,则应当把B重载为A类的成员函数,该函数只有一个形参,形参的类型是oprd2所属的类型。经过重载后,表达式oprd1 B oprd2 就相当于函数调用 oprd1.operator B(oprd2). 第4章运算符重载 4.1 什么是运算符重载 所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新功能。 运算符也可以重载。实际上,我们已经在不知不觉之中使用了运算符重载。如:+可以对int、float、double的数据进行加法运算。 现在要讨论的问题是:用户能否根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。譬如,能否用“+”号进行两个复数、两个点的相加。在C++中不能在程序中直接用运算符“+”对复数进行相加运算。用户必须自己设法实现复数相加。 例如用户可以通过定义一个专门的函数来实现复数相加。见下例。 //例4.1 通过函数来实现复数相加。 #include 习题二 一、填空题 1. 对运算符进行重载时,不能改变结合性,不能改变操作数个数,不能改变优先级。 2. 当++被重载为后置成员函数时需要0 个参数。 3. 当++被重载为前置成员函数时需要 1 个参数。 4. 在C++中,运算符重载函数可以是成员函数,也可以是友元函数,还可以是普通函数。 5. 友元破坏了类的封装性特性。 6. 类的友元能够访问这个类的所有成员。 7. 类的静态数据成员的初始化是在类外进行的。 8. 类的静态成员函数没有this指针。 9. 类的静态成员函数访问该类的非静态成员可以通过参数传递对象来实现。 10. 不能被重载的类成员函数是构造和析构函数。 二、选择题 1. 已知类A有一个带double型参数的构造函数,且将运算符“+”重载为该类友元函数,若如下语句:A x( 2.5),y( 3.6),z(0); z=x+y; 能够正常运行,运算符重载函数operator+ 应在类中声明为( D )。 A. friend A operator+ (double , double) ; B. friend A operator+ ( double , A &); C. friend A operator+ ( A &, double); D. friend A operator+ ( A & , A &); 2. 下列关于运算符重载的描述中,正确的是(D )。 A. 运算符重载可以改变操作数的个数 B. 运算符重载可以改变优先级 C. 运算符重载可以改变结合性 D. 运算符重载不可以改变语法结构 3. 友元运算符表达式obj1>obj2被C++编译器解释为(A )。 A. operator>(obj1,obj2) B. >(obj1,obj2) C. obj2.operator>(obj1) D. obj1.operator>(obj2) 4. 下列关于C++运算符函数的返回类型的描述中,错误的是(C )。 A. 可以是类类型 B. 可以是int类型 C++习题参考答案 第1章面向对象程序设计概论 一、名词解释 抽象封装消息 【问题解答】 面向对象方法中得抽象就是指对具体问题(对象)进行概括,抽出一类对象得公共性质并加 以描述得过程、 面向对象方法中得封装就就是把抽象出来得对象得属性与行为结合成一个独立得单位,并 尽可能隐蔽对象得内部细节。 消息就是面向对象程序设计用来描述对象之间通信得机制。一个消息就就是一个对象要求另一个对象实施某种操作得一个请求。 二、填空题 (1) 目前有面向过程得结构化程序设计方法与面向对象得程序设计方法两种重要得程序设计方法。 (2) 结构化程序设计方法中得模块由顺序、选择与循环3种基本结构组成。 (3) 在结构化程序设计方法中,程序可表示为程序=数据结构+算法; 而面向对象得程序设计 方法,程序可表示为程序=对象+消息。 (4) 结构化程序设计方法中得基本模块就是过程; 而面向对象程序设计方法中得基本模块就是类。 (5) 面向对象程序设计方法具有抽象性、封装性、继承性与多态性等特点、 三、选择题(至少选一个,可以多选) (1) 面向对象程序设计着重于( B )得设计。 A。对象B。类C、算法D、数据 (2) 面向对象程序设计中,把对象得属性与行为组织在同一个模块内得机制叫做( C )。A、抽象 B。继承 C。封装D. 多态 (3) 在面向对象程序设计中,类通过( D )与外界发生关系。 A、对象 B. 类C、消息D。接口 (4) 面向对象程序设计中,对象与对象之间得通信机制就是( C )。 A、对象 B。类 C. 消息 D、接口 (5) 关于C++与C语言得关系得描述中,( D )就是错误得、 A、 C语言就是C++得一个子集B、C语言与C++就是兼容得 C. C++对C语言进行了一些改进 D. C++与C语言都就是面向对象得 【结果分析】 C语言就是面向过程得。C++语言就是一种经过改进得更为优化得C语言,就是一种混合型语言,既面向过程也面向对象、 (6) 面向对象得程序设计将数据结构与( A )放在一起,作为一个相互依存、不可分割得整体来处理。 A、算法 B。信息C、数据隐藏 D、数据抽象 (7) 下面( A )不就是面向对象系统所包含得要素。 A。重载 B、对象 C. 类 D。继承 【结果分析】 面向对象=对象+类+继承+消息+多态 (8) 下面说法正确得就是( BC )。 A。将数据结构与算法置于同一个函数内,即为数据封装 B。一个类通过继承可以获得另一个类得特性 C。面向对象要求程序员集中于事物得本质特征,用抽象得观点瞧待程序 D。同一消息为不同得对象接受时,产生得行为就是一样得,这称为一致性 【结果分析】 C++程序设计练习题 一、填空题 1.对象的三大基本特性分别为多态性、( )、封装性。 2.赋值运算符应重载为( )函数。 3.用( )声明的基类称为虚基类。 4.用( )声明的函数称为虚函数。 5.派生类对基类继承控制访问有三种。派生类可以定义其基类中不具备的( )。 6.静态成员是对象的成员,( )函数不是类的成员。 7.在函数体之前加( )关键字可以防止覆盖函数改变数据成员的值。 8.一个const对象只能访问( )成员函数。 9.使用友元函数是为了提高程序效率,且节约了( )开销。 10.类名为“ClassName”的类,其拷贝构造函数的原型说明是( )。 11.由关键字private、public和protected限定成员的访问权限分别是( )、( )和( )。缺省关键字时成员的访问权限为( )。 12.如果想要公共基类在派生类中只有一个拷贝,就要将公共的基类说明为( );如果虚基类没有默认构造函数,就必须在每一个派生类的构造函数中都要调用虚基类的( )函数。 13.静态成员函数是使用关键字( )说明的成员函数。 14.一个函数的原型声明为“void FunName(int=0, double=0, char='x');”,则调用FunName函数的方法共有( )种。 15.编译时多态性是通过( )实现的;运行时多态性是通过( )实现的。 16.C++通过( )实现编译时多态性,通过( )实现运行时多态性。 17.在C++中,声明类的关键字是( )。 18.声明C++模板的关键字是( )。 19.调用函数原型声明为“void FunName(short, int=0, float=1.0);”的方法有( )种。 20.处理C++异常的方法:采用( )结构。 21.用关键字( )、( )和( )限定的成员,其访问权限分别为:公有的、私有的和保护的。缺省关键字时,成员的访问权限为( )。 22.在C++中,处理( )的方法是采用try-catch结构。 23.在C++中,用关键字( )说明内置函数。 24.在C++中,声明友元函数的关键字是( )。 25.将公共基类说明为( )时,多重派生过程中公共基类在派生类中就只有一个拷贝了。 26.在C++中,如果函数调用在前、定义在后,就必须先对函数进行( )。 27.在成员函数头之后、函数体之前加( )修饰的成员函数称为类的常成员函数。 28.包含纯虚函数的类称为抽象类,这种类只能用作( )来派生新类。由于抽象类的特殊性,我们可以说明抽象类的( ),但不能说明抽象类的( )。 29.说明函数类型为“double”、函数名为“virfun”且无参数的纯虚函数的表达形式为( )。 30.说明静态成员要使用关键字( )。 运算符重载(operator overload) 是c++的一个重要的新特性,它使得程序员把c++运算符定义扩展到操作数是对象的情况.运算符重载的目的是使c++程序更加直观,更易懂. 运算符重载和普通的重载一样: 作用域相同,函数名字相同,但参数不同(参数个数,参数的类型) , 注意如果函数名字相同,参数相同但函数的返回值类型不同这不是重载,这是错误! 返回值类型operator 被重载的运算符(参数...){函数的实现} 具体的例子网上有很多, 我的重点是一些我们在写重载中易忽略的一些小问题. 有时候我们的程序在多数情况下是对的但有时也总有一些出乎我们意料的情况: 请看下面这个程序: #include C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作。例如: class complex { public: complex(double r=0.0,double I=0.0){real=r;imag=I;} void display(); private: double real; double imag; }; complex a(10,20),b(5,8); “a+b”运算如何实现?这时候我们需要自己编写程序来说明“+”在作用于complex类对象时,该实现什么样的功能,这就是运算符重载。运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为。 运算符重载的实质是函数重载。在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用达标函数,这个过程爱编译过程中完成。 一、运算符重载的规则 运算符重载规则如下: ①、C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。 ②、重载之后运算符的优先级和结合性都不会改变。 ③、运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 不能重载的运算符只有五个,它们是:成员运算符“.”、指针运算符“*”、作用域运算符“::”、“sizeof”、条件运算符“?:”。 运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。 运算符重载为类的成员函数的一般语法形式为: 函数类型 operator 运算符(形参表) { 函数体; } 运算符重载为类的友元函数的一般语法形式为: friend 函数类型 operator 运算符(形参表) { 函数体; } 其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。 当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;当重载为类 第10章运算符重载 一、选择题 1.在下列运算符中,不能重载的是( )。 (a) ! (b) sizeof (c) new (d) delete 2. 在下列运算符中,不能重载的是( )。 (a) <= (b) >> (c) && (d) &= 3.下列关于运算符重载的描述中,( )是正确的。 (a) 可以改变参与运算的操作数个数 (b) 可以改变运算符原来的优先级 (c) 可以改变运算符原来的结合性(d) 不能改变原运算符的语义 4.下列函数中,能重载运算符的函数是( b,c )。 (a) 成员函数(b) 构造函数(c) 析构函数 (d) 友员函数 5.不能用友员函数重载的是( a )。 (a) = (b) == (c) += (d) != 6.下面描述中,错误的是( b )。 (a) 只有系统预先定义的运算符才可能被重载 (b) 使用类型转换函数不能把一个类转换为另一个类 (c) 使用类型转换函数可以把类转换为基本类型 (d) 类型转换函数只能定义为一个类的成员函数,不能定义为类的友员函数 二、阅读下列程序,写出执行结果 1.#include 第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. 设有以下类定义,其中说明了“+”运算符重载函数的原型。这是一个友元函数,当类运算符重载基础概念练习题
c 运算符的重载习题答案
C++期末复习--1.练习题_选择
C中用运算符重载实现矩阵运算
运算符重载练习题.
c++运算符重载习题
第十章 运算符重载 复习题
运算符重载题目
第7章 运算符重载-习题
C++运算符重载
运算符重载
习题二C++练习(含有答案)
C++第13章答案
C++程序设计练习题与答案(1)
运算符重载注意
C++运算符重载讲解与经典实例 (2)
运算符重载练习1
第11章 运算符重载 习题解答