《第13章运算符重载精.ppt》由会员分享,可在线阅读,更多相关《第13章运算符重载精.ppt(54页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第1313章运算符重载章运算符重载第1页,本讲稿共54页讲授内容讲授内容n运算符重载的概念运算符重载的概念n以成员函数的方式重载运算符以成员函数的方式重载运算符n以友元函数的方式重载运算符以友元函数的方式重载运算符n流插入和流提取运算符的重载流插入和流提取运算符的重载n一般单目和双目运算符的重载一般单目和双目运算符的重载n赋值运算符重载赋值运算符重载n类型转换运算符重载类型转换运算符重载第2页,本讲稿共54页13.1 13.1 运算符重载的概念运算符重载的概念 (1/2)(1/2)n类似于函数重载类似于函数重载n把传统的运算符用于用户自定义的对象把传统的运算符用于用户自定义的对象n直观自然,
2、可以提高程序的可读性直观自然,可以提高程序的可读性n体现了体现了C+C+的可扩充性的可扩充性n通过定义名为通过定义名为operator的函的函数来实现运算符重载数来实现运算符重载第3页,本讲稿共54页例例1 1:复数的、运算:复数的、运算 (1/5)(1/5)/文件文件1:complex1.h复数类的定义复数类的定义#ifndefCOMPLEX1_H#defineCOMPLEX1_HclassComplexpublic:Complex(double=0.0,double=0.0);Complexoperator+(constComplex&)const;Complexoperator-(con
3、stComplex&)const;Complex&operator=(constComplex&);voidprint()const;private:doublereal;/realpartdoubleimaginary;/imaginarypart;#endif第4页,本讲稿共54页例例1 1:复数的、运算:复数的、运算 (2/5)(2/5)/文件文件2:complex1.cpp复数类的成员函数定义复数类的成员函数定义#include#includecomplex1.hComplex:Complex(doubler,doublei)real=r;imaginary=i;Complex Com
4、plex:operator+(const Complex&operand2)constComplex Complex:operator+(const Complex&operand2)constComplexsum;sum.real=real+operand2.real;sum.imaginary=imaginary+operand2.imaginary;returnsum;第5页,本讲稿共54页例例1 1:复数的、运算:复数的、运算 (3/5)(3/5)Complex Complex:operator-(const Complex&operand2)constComplex Complex:
5、operator-(const Complex&operand2)constComplexdiff;diff.real=real-operand2.real;diff.imaginary=imaginary-operand2.imaginary;returndiff;Complex&Complex:operator=(constComplex&right)real=right.real;imaginary=right.imaginary;return*this;/enablesconcatenationvoidComplex:print()constcout(real,imaginary);第
6、6页,本讲稿共54页例例1 1:复数的、运算:复数的、运算 (4/5)(4/5)/文件文件3:FIG13_1.cpp主函数定义主函数定义#include#includecomplex1.hmain()Complexx,y(4.3,8.2),z(3.3,1.1);coutx:;x.print();coutny:;y.print();coutnz:;z.print();x=y+z;coutnnx=y+z:n;第7页,本讲稿共54页例例1 1:复数的、运算:复数的、运算 (5/5)(5/5)x.print();cout=;y.print();cout+;z.print();x=y-z;coutnnx
7、=y-z:n;x.print();cout=;y.print();cout-;z.print();cout =()-=的重载函数必须是类的成员函数的重载函数必须是类的成员函数第10页,本讲稿共54页13.2 13.2 运算符成员函数与友元函数运算符成员函数与友元函数 (1/2)(1/2)n以成员函数的方式重载运算符以成员函数的方式重载运算符n单目运算符:不带参数,该类对象为唯一操作数单目运算符:不带参数,该类对象为唯一操作数n双目运算符:带一个参数,该类对象为左操作数、双目运算符:带一个参数,该类对象为左操作数、参数为右操作数参数为右操作数n以友元函数的方式重载运算符以友元函数的方式重载运算符
8、n单目运算符:带一个参数,该参数为唯一操作数,单目运算符:带一个参数,该参数为唯一操作数,是自定义类的对象是自定义类的对象n双目运算符:带两个参数,第一个参数为左操作数、双目运算符:带两个参数,第一个参数为左操作数、第二个参数为右操作数,至少有一个参数为自定义第二个参数为右操作数,至少有一个参数为自定义类的对象类的对象第11页,本讲稿共54页13.2 13.2 运算符成员函数与友元函数运算符成员函数与友元函数 (2/2)(2/2)n如果双目运算符的左操作数不是自定义类如果双目运算符的左操作数不是自定义类的对象,重载函数不能定义为成员函数的对象,重载函数不能定义为成员函数n流插入运算符流插入运算
9、符的重载的重载n运算符可交换性的实现(两个不同类型的操作运算符可交换性的实现(两个不同类型的操作数)数)n运算符重载函数的定义要保证运算无二义运算符重载函数的定义要保证运算无二义性性第12页,本讲稿共54页13.3 13.3 单目运算符重载单目运算符重载 (1/3)(1/3)n操作数是自定义类的对象或对象的引用操作数是自定义类的对象或对象的引用n作为成员函数重载作为成员函数重载n没有参数没有参数n作为友元函数重载作为友元函数重载n参数为自定义类的对象或对象的引用参数为自定义类的对象或对象的引用 第13页,本讲稿共54页例例2 2:定义字符串类:定义字符串类StringString,并以成员函数
10、的方式重并以成员函数的方式重载运算符载运算符!以判断对象中的字符串是否为空串以判断对象中的字符串是否为空串 (1/3)(1/3)/文件文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassStringpublic:String(char*m=);/使用默认参数的构造函数使用默认参数的构造函数String();/定义运算符重载成员函数原型定义运算符重载成员函数原型booloperator!();private:char*str;#endif第14页,本讲稿共54页例例2 2:定义字符串类:定义字符串类StringString,并
11、以成员函数的方式重载并以成员函数的方式重载运算符运算符!以判断对象中的字符串是否为空串以判断对象中的字符串是否为空串(2/3)(2/3)/文件文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;boolString:operator!()/实现运算符重载函数实现运算符重载函数if(strlen(str)=0)returntrue;returnfalse;第15页,本讲稿共54页例例2 2:定义字符串类:定义字符
12、串类StringString,并以成员函数的方式重载并以成员函数的方式重载运算符运算符!以判断对象中的字符串是否为空串以判断对象中的字符串是否为空串(3/3)(3/3)/文件文件ex13_1.cpp#include#includeString.hmain()Strings1,s2(somestring);if(!s1)/括号中等价于括号中等价于s1.operator!()couts1isNULL!endl;elsecouts1isnotNULL!endl;if(!s2)couts2isNULL!endl;elsecouts2isnotNULL!endl;return0;第16页,本讲稿共54页
13、程序执行结果:程序执行结果:s1isNULL!s2isnotNULL!第17页,本讲稿共54页例例3 3:定义字符串类:定义字符串类StringString,并以友元函数的方式重载并以友元函数的方式重载运算符运算符!以判断对象中的字符串是否为空串以判断对象中的字符串是否为空串(1/3)(1/3)/文件文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassString/定义运算符重载友元函数原型定义运算符重载友元函数原型friendbooloperator!(String&s);public:String(char*m=);St
14、ring();private:char*str;#endif第18页,本讲稿共54页例例3 3:定义字符串类:定义字符串类StringString,并以友元函数的方式重载并以友元函数的方式重载运算符运算符!以判断对象中的字符串是否为空串以判断对象中的字符串是否为空串(2/3)(2/3)/文件文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;booloperator!(String&s)/实现运算符重载友元函数
15、实现运算符重载友元函数if(strlen(s.str)=0)returntrue;returnfalse;第19页,本讲稿共54页例例3 3:定义字符串类:定义字符串类StringString,并以友元函数的方式重载运并以友元函数的方式重载运算符算符!以判断对象中的字符串是否为空串以判断对象中的字符串是否为空串(3/3)(3/3)/文件文件ex13_2.cpp#include#includeString.hmain()Strings1,s2(somestring);if(!s1)/括号中等价于括号中等价于operator!(s1)couts1isNULL!endl;elsecouts1isno
16、tNULL!endl;if(!s2)couts2isNULL!endl;else couts2isnotNULL!endl;return0;第20页,本讲稿共54页程序执行结果:程序执行结果:s1isNULL!s2isnotNULL!第21页,本讲稿共54页13.3 13.3 单目运算符重载单目运算符重载 (2/3)(2/3)n特殊的单目运算符特殊的单目运算符+、-以以+为例(为例(-同理同理),设设b b为类为类C C的对象的对象n前自增,如:前自增,如:+b+bn重载函数可为重载函数可为C C的成员函数,原型为的成员函数,原型为 C&C&operator+();operator+();n也
17、可为也可为C C的友元函数,原型为的友元函数,原型为 C&C&operator+(C&);operator+(C&);第22页,本讲稿共54页13.3 13.3 单目运算符重载单目运算符重载 (3/3)(3/3)n后自增,如:后自增,如:b+b+n重载函数可为重载函数可为C C的成员函数,原型为的成员函数,原型为 C&operator+(int);C&operator+(int);b+b+转换为函数调用转换为函数调用b.operator+(0)b.operator+(0)n重载函数也可为重载函数也可为C C的友元函数,原型为的友元函数,原型为 C&operator+(C&,int);C&ope
18、rator+(C&,int);b+b+转换为函数调用转换为函数调用operator+(boperator+(b,0)0)第23页,本讲稿共54页13.4 13.4 重载流插入和流提取运算符重载流插入和流提取运算符(1/2)(1/2)ncout+cout+可以输出预定义类型的对象可以输出预定义类型的对象如:如:coutstring;ncoutcout是类是类ostreamostream的一个对象(定义于头文的一个对象(定义于头文件件ostream.hostream.h中)中)n如何实现用如何实现用coutcout输出自定义类型的对象?输出自定义类型的对象?Strings(string);cout
19、sendl;第24页,本讲稿共54页13.4 13.4 重载流插入和流提取运算符重载流插入和流提取运算符(2/2)(2/2)n应重载为成员函数还是友元函数应重载为成员函数还是友元函数?n有选择吗?有选择吗?n重载函数的返回类型应该是什么?重载函数的返回类型应该是什么?n有选择吗?有选择吗?n重载函数的参数列表应该是什么?重载函数的参数列表应该是什么?n有选择吗?有选择吗?第25页,本讲稿共54页例例4 4:定义字符串类:定义字符串类StringString,并重载流插入运算符并重载流插入运算符,实现用,实现用coutcout和和cincin直接输出和输直接输出和输入类入类StringStrin
20、g的对象的对象(1/4)(1/4)/文件文件string.h#if!defined_STRING_H_#define_STRING_H_#include#includeclassStringfriend ostream&operator(ostream&output,String&s);friend ostream&operator(istream&input,String&s);friend istream&operator(istream&input,String&s);public:String(char*m=);String();private:char*str;#endif第26页,
21、本讲稿共54页例例4 4:定义字符串类:定义字符串类StringString,并重载流插入运算符并重载流插入运算符,实现用,实现用coutcout和和cincin直接输出和输入直接输出和输入类类StringString的对象的对象(2/4)(2/4)/文件文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;第27页,本讲稿共54页例例4 4:定义字符串类:定义字符串类StringString,并重载流插入运算符
22、并重载流插入运算符,实现用,实现用coutcout和和cincin直接输出和直接输出和输入类输入类StringString的对象的对象(3/4)(3/4)/定义运算符定义运算符重载函数重载函数ostream&operator(ostream&output,String&s)output重载函数重载函数istream&operator(istream&input,String&s)chartemp1000;cintemp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;第28页,本讲稿共54页例例4 4
23、:定义字符串类:定义字符串类StringString,并重载流插入运算符并重载流插入运算符,实现用,实现用coutcout和和cincin直接输出和输入直接输出和输入类类StringString的对象的对象(4/4)(4/4)/文件文件ex13_3.cpp#include#includeString.hmain()Strings1,s2;coutPleaseinputtwostrings:s1s2;coutOutputis:endl;couts1-s1endls2-s2endl;return0;第29页,本讲稿共54页程序执行结果:程序执行结果:Pleaseinputtwostrings:Wu
24、hanChangshaOutputis:s1-Wuhans2-Changsha第30页,本讲稿共54页13.5 13.5 双目运算符重载双目运算符重载(1/2)(1/2)n双目运算符的重载形式,考虑双目运算符的重载形式,考虑n运算符对左操作数是否有要求运算符对左操作数是否有要求n是否要保留运算符的可交换性(只针对具有可交换性的运算符是否要保留运算符的可交换性(只针对具有可交换性的运算符而言)而言)n双目运算符重载为非静态成员函数双目运算符重载为非静态成员函数n带有一个参数带有一个参数n左操作数必须为该类的对象或对象的引用左操作数必须为该类的对象或对象的引用n双目运算符重载为带有两个参数的非成员
25、函数双目运算符重载为带有两个参数的非成员函数n参数之一必须是类的对象或对象的引用参数之一必须是类的对象或对象的引用第31页,本讲稿共54页例例5 5:定义类:定义类StringString,重载运算符重载运算符+=+=,x+=yx+=y将将y y中中的字符串连接到的字符串连接到x x的后面的后面(1/5)(1/5)/文件文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassStringfriend ostream&operator(ostream&output,String&s);friend ostream&operator
26、(istream&input,String&s);friend istream&operator(istream&input,String&s);public:String(char*m=);String();String&operator+=(String&s);private:char*str;#endif第32页,本讲稿共54页例例5 5:定义类:定义类StringString,重载运算符重载运算符+=+=,x+=yx+=y将将y y中的字符串连接到中的字符串连接到x x的后面的后面(2/5)(2/5)/文件文件String.cpp,类类String的实现的实现#include#incl
27、udestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;/定义运算符定义运算符重载函数重载函数ostream&operator(ostream&output,String&s)output重载函数重载函数istream&operator(istream&input,String&s)chartemp1000;cintemp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;
28、第34页,本讲稿共54页例例5 5:定义类:定义类StringString,重载运算符重载运算符+=+=,x+=yx+=y将将y y中中的字符串连接到的字符串连接到x x的后面的后面(4/5)(4/5)/定义运算符定义运算符+=重载函数重载函数String&String:operator+=(String&s)chartemp4096;strcpy(temp,str);strcat(temp,s.str);deletestr;str=newcharstrlen(temp)+1;strcpy(str,temp);return*this;第35页,本讲稿共54页例例5 5:定义类:定义类Strin
29、gString,重载运算符重载运算符+=+=,x+=yx+=y将将y y中中的字符串连接到的字符串连接到x x的后面的后面(5/5)(5/5)/文件文件ex13_4.cpp,测试重载的运算符测试重载的运算符#include#includeString.hmain()Strings1,s2;cins1s2;couts1-s1endl;s1+=s2;couts1afters1+=s2-s1endl;return0;第36页,本讲稿共54页程序执行结果:程序执行结果:WuhanChangshas1-Wuhans1afters1+=s2-WuhanChangsha第37页,本讲稿共54页13.5 13
30、.5 双目运算符重载双目运算符重载(2/2)(2/2)n如果要使用友元的方式重载前面例子中如果要使用友元的方式重载前面例子中的的+=+=,要如何考虑?,要如何考虑?n函数名?函数名?n参数列表?参数列表?n返回类型?返回类型?n返回值?返回值?第38页,本讲稿共54页用友元函数重载运算符用友元函数重载运算符 +classString/声明友元函数声明友元函数operator+=friend String&operator+=(String&x,String&y);friend String&operator+=(String&x,String&y);.;/运算符重载函数运算符重载函数opera
31、tor+=的实现的实现String&operator+=(String&x,String&y)chartemp4096;strcpy(temp,x.str);strcat(temp,y.str);deletex.str;x.str=newcharstrlen(temp)+1;strcpy(x.str,temp);returnx;第39页,本讲稿共54页13.6 13.6 赋值运算符重载赋值运算符重载(1/2)(1/2)n赋值运算符可直接用在自定义类的对象赋值赋值运算符可直接用在自定义类的对象赋值n默认操作是逐个拷贝对象的所有数据成员默认操作是逐个拷贝对象的所有数据成员n如果对象中包含动态分配的
32、空间,这种赋值如果对象中包含动态分配的空间,这种赋值方式就不合适了,如方式就不合适了,如 String s1(abc),s2(def);String s1(abc),s2(def);s1=s2;s1=s2;赋值的结果是:对象赋值的结果是:对象s1s1和和s2s2的指针的指针strstr都指向了同都指向了同一块数据空间一块数据空间第40页,本讲稿共54页13.6 13.6 赋值运算符重载赋值运算符重载(2/2)(2/2)n问题:问题:n存放存放“abcabc”的空间被遗弃,将无法被访问的空间被遗弃,将无法被访问n如果对象如果对象s1s1被撤销被撤销n其析构函数将释放其指针其析构函数将释放其指针s
33、trstr所指向的空间所指向的空间“defdef”n对象对象s2s2的指针的指针strstr所指向的空间被破坏所指向的空间被破坏n访问访问s2s2的数据、撤销的数据、撤销s2s2时都会发生指针错误时都会发生指针错误n对象中包含动态分配的空间,赋值运算符需要自己重载对象中包含动态分配的空间,赋值运算符需要自己重载第41页,本讲稿共54页例例6 6:定义类:定义类StringString,重载运算符重载运算符+和和=(1/6)=(1/6)/文件文件string.hstring.h,定义类定义类StringString#if!defined_STRING_H_#define_STRING_H_#in
34、cludeclassStringfriend ostream&operator(ostream&output,String&s);friend ostream&operator(istream&input,String&s);friend istream&operator(istream&input,String&s);public:String(char*m=);String();String&operator=(String&s);String&operator+(String&s);private:char*str;#endif第42页,本讲稿共54页例例6 6:定义类:定义类Strin
35、gString,重载运算符重载运算符+和和=(2/6)=(2/6)/文件文件String.cpp,类类String的实现的实现#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;/定义运算符定义运算符重载函数重载函数ostream&operator(ostream&output,String&s)output重载函数重载函数istream&operator(istream&input,String&s)chartemp1000;cin
36、temp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;第44页,本讲稿共54页例例6 6:定义类:定义类StringString,重载运算符重载运算符+和和=(4/6)=(4/6)String&String:operator=(String&s)if(&s=this)/检查是否自我赋值,非常重要检查是否自我赋值,非常重要 return*this;deletestr;/释放当前对象的数据空间释放当前对象的数据空间str=newcharstrlen(s.str)+1;/重新分配适当大小的空间重新分配适
37、当大小的空间strcpy(str,s.str);return*this;第45页,本讲稿共54页例例6 6:定义类:定义类StringString,重载运算符重载运算符+和和=(5/6)=(5/6)String&String:operator+(String&s)staticStringres;/为什么要声明为什么要声明res为静态对象为静态对象chartemp4096;strcpy(temp,str);strcat(temp,s.str);deleteres.str;res.str=newcharstrlen(temp)+1;strcpy(res.str,temp);returnres;第4
38、6页,本讲稿共54页例例6 6:定义类:定义类StringString,重载运算符重载运算符+和和=(6/6)=(6/6)/文件文件ex13_5.cpp,测试重载的运算符测试重载的运算符#include#includeString.hmain()Strings1,s2;coutPleaseinputtwostrings:s1s2;coutOutputis:endl;couts1-s1endl;couts2-s2endl;s1=s1+s2;coutafters1=s1+s2;endl;couts1-s1endl;return0;第47页,本讲稿共54页程序执行结果:程序执行结果:Pleasein
39、puttwostrings:WuhanChangshaOutputis:s1-Wuhans2-Changshaafters1=s1+s2;s1-WuhanChangsha第48页,本讲稿共54页13.7 13.7 类型之间的转换类型之间的转换 (1/4)(1/4)n自定义类的对象和其它类型之间也可以实现自定义类的对象和其它类型之间也可以实现隐式或显式的转换隐式或显式的转换n类似提升和类型强制转换类似提升和类型强制转换n两种类型转换方式两种类型转换方式n其它类型的数据到自定义类的对象的转换其它类型的数据到自定义类的对象的转换n通过转换构造函数通过转换构造函数n自定义类的对象到其它类型的数据的转换
40、自定义类的对象到其它类型的数据的转换n通过类型转换运算符函数通过类型转换运算符函数第49页,本讲稿共54页13.7 13.7 类型之间的转换类型之间的转换 (2/4)(2/4)n类型转换运算符函数类型转换运算符函数n必须是类的非静态成员函数,不能是友元函数必须是类的非静态成员函数,不能是友元函数n没有参数(操作数是什么?)没有参数(操作数是什么?)n不能指定返回类型(其实已经指定了)不能指定返回类型(其实已经指定了)第50页,本讲稿共54页13.7 13.7 类型之间的转换类型之间的转换 (3/4)(3/4)n类型转换运算符函数名:类型转换运算符函数名:operator+operator+类型
41、名类型名n例子:例子:operator int()const;operator int()const;将类的对象转换成一个将类的对象转换成一个intint类型的数据类型的数据n如果如果objobj是该自定义类的一个对象,则:是该自定义类的一个对象,则:(int)obj;int)obj;等价于:等价于:obj.operator int();obj.operator int();该函数根据对象该函数根据对象objobj生成一个生成一个intint类型的数据类型的数据n需要的时候,编译器会自动调用类型转换运算符函数来建立需要的时候,编译器会自动调用类型转换运算符函数来建立一个临时对象一个临时对象n就
42、像对内部类型使用提升规则一样就像对内部类型使用提升规则一样 第51页,本讲稿共54页13.7 13.7 类型之间的转换类型之间的转换 (4/4)(4/4)n转换构造函数转换构造函数n只有一个参数,就是其它类型的对象只有一个参数,就是其它类型的对象n根据该对象初始化自定义类型的对象根据该对象初始化自定义类型的对象n转换构造函数例子转换构造函数例子String(constchar*m=);String(constintlen);第52页,本讲稿共54页学习目的检测学习目的检测n了解运算符重载的概念和意义了解运算符重载的概念和意义n掌握运算符重载的限制掌握运算符重载的限制n掌握流插入和流提取运算符的重载方法掌握流插入和流提取运算符的重载方法n掌握以成员函数的方式重载运算符的方法掌握以成员函数的方式重载运算符的方法n掌握以友元函数的方式重载运算符的方法掌握以友元函数的方式重载运算符的方法n了解运算符成员函数和友元函数的区别了解运算符成员函数和友元函数的区别n掌握赋值运算符重载的方法掌握赋值运算符重载的方法n了解类型转换运算符的重载方法了解类型转换运算符的重载方法第53页,本讲稿共54页作业作业13.3 13.6 13.813.3 13.6 13.8第54页,本讲稿共54页