C语言程序设计下.pptx
《C语言程序设计下.pptx》由会员分享,可在线阅读,更多相关《C语言程序设计下.pptx(240页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第13章 运算符重载第1页/共240页讲授内容运算符重载的概念以成员函数的方式重载运算符以友元函数的方式重载运算符流插入和流提取运算符的重载一般单目和双目运算符的重载赋值运算符重载类型转换运算符重载第2页/共240页13.1 运算符重载的概念(1/2)类似于函数重载把传统的运算符用于用户自定义的对象直观自然,可以提高程序的可读性体现了C+的可扩充性通过定义名为operator的函数来实现运算符重载第3页/共240页例1:复数的、运算(1/5)/文件1:complex1.h复数类的定义#ifndefCOMPLEX1_H#defineCOMPLEX1_HclassComplexpublic:Com
2、plex(double=0.0,double=0.0);Complexoperator+(constComplex&)const;Complexoperator-(constComplex&)const;Complex&operator=(constComplex&);voidprint()const;private:doublereal;/realpartdoubleimaginary;/imaginarypart;#endif第4页/共240页例1:复数的、运算(2/5)/文件2:complex1.cpp复数类的成员函数定义#include#includecomplex1.hComplex
3、:Complex(doubler,doublei)real=r;imaginary=i;Complex Complex:operator+(const Complex&operand2)constComplexsum;sum.real=real+operand2.real;sum.imaginary=imaginary+operand2.imaginary;returnsum;第5页/共240页例1:复数的、运算(3/5)Complex Complex:operator-(const Complex&operand2)constComplexdiff;diff.real=real-operan
4、d2.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页/共240页例1:复数的、运算(4/5)/文件3:FIG13_1.cpp主函数定义#include#includecomplex1.hma
5、in()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页/共240页例1:复数的、运算(5/5)x.print();cout=;y.print();cout+;z.print();x=y-z;coutnnx=y-z:n;x.print();cout=;y.print();cout-;z.print();cout =的重载函数必须是类的成员函数第10页/共240页13.2 运算符成员函数与友元函数(1/2)以成员函数的方式重载运算符
6、单目运算符:不带参数,该类对象为唯一操作数双目运算符:带一个参数,该类对象为左操作数、参数为右操作数以友元函数的方式重载运算符单目运算符:带一个参数,该参数为唯一操作数,是自定义类的对象双目运算符:带两个参数,第一个参数为左操作数、第二个参数为右操作数,至少有一个参数为自定义类的对象第11页/共240页13.2 运算符成员函数与友元函数(2/2)如果双目运算符的左操作数不是自定义类的对象,重载函数不能定义为成员函数流插入运算符的重载运算符可交换性的实现(两个不同类型的操作数)运算符重载函数的定义要保证运算无二义性第12页/共240页13.3 单目运算符重载(1/3)操作数是自定义类的对象或对象
7、的引用作为成员函数重载没有参数作为友元函数重载参数为自定义类的对象或对象的引用 第13页/共240页例2:定义字符串类String,并以成员函数的方式重载运算符!以判断对象中的字符串是否为空串(1/3)/文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassStringpublic:String(char*m=);/使用默认参数的构造函数String();/定义运算符重载成员函数原型booloperator!();private:char*str;#endif第14页/共240页例2:定义字符串类String,并以成员函数的方
8、式重载运算符!以判断对象中的字符串是否为空串(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页/共240页例2:定义字符串类String,并以成员函数的方式重载运算符!以判断对象中的字符串是否为空串(3/3)/文件ex13_1.cpp#includ
9、e#includeString.hmain()Strings1,s2(somestring);if(!s1)/括号中等价于s1.operator!()couts1isNULL!endl;elsecouts1isnotNULL!endl;if(!s2)couts2isNULL!endl;elsecouts2isnotNULL!endl;return0;第16页/共240页程序执行结果:s1isNULL!s2isnotNULL!第17页/共240页例3:定义字符串类String,并以友元函数的方式重载运算符!以判断对象中的字符串是否为空串(1/3)/文件string.h#if!defined_ST
10、RING_H_#define_STRING_H_#includeclassString/定义运算符重载友元函数原型friendbooloperator!(String&s);public:String(char*m=);String();private:char*str;#endif第18页/共240页例3:定义字符串类String,并以友元函数的方式重载运算符!以判断对象中的字符串是否为空串(2/3)/文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);St
11、ring:String()deletestr;booloperator!(String&s)/实现运算符重载友元函数if(strlen(s.str)=0)returntrue;returnfalse;第19页/共240页例3:定义字符串类String,并以友元函数的方式重载运算符!以判断对象中的字符串是否为空串(3/3)/文件ex13_2.cpp#include#includeString.hmain()Strings1,s2(somestring);if(!s1)/括号中等价于operator!(s1)couts1isNULL!endl;elsecouts1isnotNULL!endl;if
12、(!s2)couts2isNULL!endl;elsecouts2isnotNULL!endl;return0;第20页/共240页程序执行结果:s1isNULL!s2isnotNULL!第21页/共240页13.3 单目运算符重载(2/3)特殊的单目运算符+、-以+为例(-同理),设b为类C的对象前自增,如:+b重载函数可为C的成员函数,原型为 C&operator+();也可为C的友元函数,原型为 C&operator+(C&);第22页/共240页13.3 单目运算符重载(3/3)后自增,如:b+重载函数可为C的成员函数,原型为 C&operator+(int);b+转换为函数调用b.o
13、perator+(0)重载函数也可为C的友元函数,原型为 C&operator+(C&,int);b+转换为函数调用operator+(b,0)第23页/共240页13.4 重载流插入和流提取运算符(1/2)cout+可以输出预定义类型的对象如:coutstring;cout是类ostream的一个对象(定义于头文件ostream.h中)如何实现用cout输出自定义类型的对象?Strings(string);coutsendl;第24页/共240页13.4 重载流插入和流提取运算符(2/2)应重载为成员函数还是友元函数?有选择吗?重载函数的返回类型应该是什么?有选择吗?重载函数的参数列表应该是
14、什么?有选择吗?第25页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和cin直接输出和输入类String的对象(1/4)/文件string.h#if!defined_STRING_H_#define_STRING_H_#include#includeclassStringfriend ostream&operator(istream&input,String&s);public:String(char*m=);String();private:char*str;#endif第26页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和
15、cin直接输出和输入类String的对象(2/4)/文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;第27页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和cin直接输出和输入类String的对象(3/4)/定义运算符重载函数ostream&operator(ostream&output,String&s)output重载函数istream&operator(istream&
16、input,String&s)chartemp1000;cintemp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;第28页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和cin直接输出和输入类String的对象(4/4)/文件ex13_3.cpp#include#includeString.hmain()Strings1,s2;cout Please input two strings:s1s2;coutOutputis:endl;couts1-s1endls2-
17、s2endl;return0;第29页/共240页程序执行结果:Pleaseinputtwostrings:WuhanChangshaOutputis:s1-Wuhans2-Changsha第30页/共240页13.5 双目运算符重载(1/2)双目运算符的重载形式,考虑运算符对左操作数是否有要求是否要保留运算符的可交换性(只针对具有可交换性的运算符而言)双目运算符重载为非静态成员函数带有一个参数左操作数必须为该类的对象或对象的引用双目运算符重载为带有两个参数的非成员函数参数之一必须是类的对象或对象的引用第31页/共240页例5:定义类String,重载运算符+=,x+=y将y中的字符串连接到x
18、的后面(1/5)/文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassStringfriend ostream&operator(istream&input,String&s);public:String(char*m=);String();String&operator+=(String&s);private:char*str;#endif第32页/共240页例5:定义类String,重载运算符+=,x+=y将y中的字符串连接到x的后面(2/5)/文件String.cpp,类String的实现#include#includ
19、estring.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;第34页/共240页例5:定义
20、类String,重载运算符+=,x+=y将y中的字符串连接到x的后面(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页/共240页例5:定义类String,重载运算符+=,x+=y将y中的字符串连接到x的后面(5/5)/文件ex13_4.cpp,测试重载的运算符#include#includeString.hm
21、ain()Strings1,s2;cins1s2;couts1-s1endl;s1+=s2;couts1afters1+=s2-s1endl;return0;第36页/共240页程序执行结果:WuhanChangshas1-Wuhans1afters1+=s2-WuhanChangsha第37页/共240页13.5 双目运算符重载(2/2)如果要使用友元的方式重载前面例子中的+=,要如何考虑?函数名?参数列表?返回类型?返回值?第38页/共240页用友元函数重载运算符+classString/声明友元函数operator+=friend String&operator+=(String&x,S
22、tring&y);.;/运算符重载函数operator+=的实现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页/共240页13.6 赋值运算符重载(1/2)赋值运算符可直接用在自定义类的对象赋值默认操作是逐个拷贝对象的所有数据成员如果对象中包含动态分配的空间,这种赋值方式就不合适了,如 String s1(abc),s2(def
23、);s1=s2;赋值的结果是:对象s1和s2的指针str都指向了同一块数据空间第40页/共240页13.6 赋值运算符重载(2/2)问题:存放“abc”的空间被遗弃,将无法被访问如果对象s1被撤销其析构函数将释放其指针str所指向的空间“def”对象s2的指针str所指向的空间被破坏访问s2的数据、撤销s2时都会发生指针错误对象中包含动态分配的空间,赋值运算符需要自己重载第41页/共240页例6:定义类String,重载运算符+和=(1/6)/文件string.h,定义类String#if!defined_STRING_H_#define_STRING_H_#includeclassStrin
24、gfriend ostream&operator(istream&input,String&s);public:String(char*m=);String();String&operator=(String&s);String&operator+(String&s);private:char*str;#endif第42页/共240页例6:定义类String,重载运算符+和=(2/6)/文件String.cpp,类String的实现#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);
25、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;第44页/共240页例6:定义类String,重载运算符+和=(4/6)String&String:operator=(String&s)if(&s=this)/检
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言程序设计
限制150内