第11章运算符重载ppt课件_第1页
第11章运算符重载ppt课件_第2页
第11章运算符重载ppt课件_第3页
第11章运算符重载ppt课件_第4页
第11章运算符重载ppt课件_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、程序设计 cs.sjtu 2011.9程序设计 - 1v什么是运算符重载什么是运算符重载 v运算符重载的方法运算符重载的方法 v几个特殊的运算符的重载几个特殊的运算符的重载 v自定义类型转换运算符自定义类型转换运算符v运算符重载实例运算符重载实例 程序设计 cs.sjtu 2011.9程序设计 - 2v使系统内置的运算符可以用于类类型使系统内置的运算符可以用于类类型v例如:例如:+ + 运算符能够实现运算符能够实现2 2个对象间的个对象间的加。例如:类加。例如:类a a的对象的对象a1a1、a2a2、a3a3,希,希望:望: a3 = a1 + a2a3 = a1 + a2; 即:分别把对象即

2、:分别把对象a1a1和和a2a2的各个数据成员的各个数据成员值对应相加,然后赋给对象值对应相加,然后赋给对象a3a3。程序设计 cs.sjtu 2011.9程序设计 - 3v把某些事交给系统去做,用户只要知道把某些事交给系统去做,用户只要知道相加就可相加就可v扩充运算符的功能扩充运算符的功能v增强了增强了c+ c+ 语言的可扩充性语言的可扩充性v使用户定义的类更像系统的内置类型使用户定义的类更像系统的内置类型程序设计 cs.sjtu 2011.9程序设计 - 4v不是所有的运算符都能重载不是所有的运算符都能重载v重载不能改变运算符的优先级和结合性重载不能改变运算符的优先级和结合性v重载不能改变

3、运算符的操作数个数重载不能改变运算符的操作数个数v不能创建新的运算符不能创建新的运算符程序设计 cs.sjtu 2011.9程序设计 - 5 + - * / % & | ! = += -= *= /= %= = &= |= = = = != = & | + - -* , - () new delete new delete程序设计 cs.sjtu 2011.9程序设计 - 6 . .* : ?: sizeof 程序设计 cs.sjtu 2011.9程序设计 - 7v什么是运算符重载什么是运算符重载 v运算符重载的方法运算符重载的方法 v几个特殊的运算符的重载几个特殊的运算符的重载 v自定义类型

4、转换运算符自定义类型转换运算符v运算符重载实例运算符重载实例 程序设计 cs.sjtu 2011.9程序设计 - 8v运算符重载就是写一个函数解释某个运算符运算符重载就是写一个函数解释某个运算符在某个类中的含义在某个类中的含义v要使得系统能自动找到重载的这个函数,函要使得系统能自动找到重载的这个函数,函数名必须要体现出和某个被重载的运算符的数名必须要体现出和某个被重载的运算符的联系。联系。vc+中规定,重载函数名为中规定,重载函数名为 operator 其中,其中,为要重载的运算符。如要重载为要重载的运算符。如要重载“+”运算符,该重载函数名为运算符,该重载函数名为operator+。要重载。

5、要重载赋值运算符,函数名为赋值运算符,函数名为operator=。 程序设计 cs.sjtu 2011.9程序设计 - 9v运算符的重载不能改变运算符的运算对象数。因此,重载运算符的重载不能改变运算符的运算对象数。因此,重载函数的形式参数个数(包括成员函数的隐式指针函数的形式参数个数(包括成员函数的隐式指针this)与运)与运算符的运算对象数相同算符的运算对象数相同 v运算符重载可以重载成成员函数也可以重载成全局函数实运算符重载可以重载成成员函数也可以重载成全局函数实现。重载成全局函数时,最好把此函数设为友员函数现。重载成全局函数时,最好把此函数设为友员函数v如果作为类的成员函数,它的形式参数

6、个数比运算符的运如果作为类的成员函数,它的形式参数个数比运算符的运算对象数少算对象数少1。这是因为成员函数有一个隐含的参数。这是因为成员函数有一个隐含的参数this。在在c+中,把隐含参数中,把隐含参数this作为运算符的第一个参数。作为运算符的第一个参数。v当把一个一元运算符重载成成员函数时,该函数没有形式当把一个一元运算符重载成成员函数时,该函数没有形式参数。参数。v把一个二元运算符重载成成员函数时,该函数只有一个形把一个二元运算符重载成成员函数时,该函数只有一个形式参数,就是右操作数,当前对象是左操作数。式参数,就是右操作数,当前对象是左操作数。程序设计 cs.sjtu 2011.9程序

7、设计 - 10v为为rational类增加类增加“+”和和“*”以及比较以及比较的重载函数,用以替换现有的的重载函数,用以替换现有的add和和multi函数函数 程序设计 cs.sjtu 2011.9程序设计 - 11class rational private:int num;int den;void reductfraction();public:rational(int n = 0, int d = 1) num = n; den = d; rational operator+(const rational &r1) const; rational operator*(const rat

8、ional &r1) const; bool operator(const rational &r1) const; bool operator=(const rational &r1) const; bool operator!=(const rational &r1) const; void display() cout num / den; 程序设计 cs.sjtu 2011.9程序设计 - 12rational rational:operator+(const rational &r1) const rational tmp; tmp.num = num * r1.den + r1.n

9、um * den; tmp.den = den * r1.den; tmp.reductfraction(); return tmp;rational rational:operator*(const rational &r1) const rational tmp; tmp.num = num * r1.num; tmp.den = den * r1.den; tmp.reductfraction(); return tmp; 程序设计 cs.sjtu 2011.9程序设计 - 13bool rational:operator(const rational &r1) const return

10、 num * r1.den (const rational &r1) const return num * r1.den den * r1.num; bool rational:operator=(const rational &r1) const return num * r1.den =(const rational &r1) const return num * r1.den = den * r1.num; bool rational:operator!=(const rational &r1) const return !(*this = r1);程序设计 cs.sjtu 2011.9

11、程序设计 - 14class rational friend rational operator+(const rational &r1, const rational &r2); friend rational operator*(const rational &r1 , const rational &r2); friend bool operator(const rational &r1 , const rational &r2) ; friend bool operator=(const rational &r1 , const rational &r2); friend bool o

12、perator!=(const rational &r1 , const rational &r2) ; private: int num;int den;void reductfraction();public:rational(int n = 0, int d = 1) num = n; den = d;void display() cout num / den;程序设计 cs.sjtu 2011.9程序设计 - 15rational operator+(const rational &r1, const rational &r2) rational tmp; tmp.num = r1.n

13、um * r2.den + r2.num * r1.den; tmp.den = r1.den * r2.den; tmp.reductfraction(); return tmp;rational operator*(const rational &r1, const rational &r2) rational tmp; tmp.num = r1.num * r2.num; tmp.den = r1.den * r2.den; tmp.reductfraction(); return tmp; 其他函数实现略其他函数实现略程序设计 cs.sjtu 2011.9程序设计 - 16int ma

14、in() rational r1(1,6), r2(1,6), r3; r3 = r1 + r2; r1.display(); cout + ; r2.display(); cout = ; r3.display(); cout endl; r3 = r1 * r2; r1.display(); cout * ; r2.display(); cout = ; r3.display(); cout )必须重载成成员函数。)必须重载成成员函数。v具有赋值意义的运算符,如复合的赋值运算符以及具有赋值意义的运算符,如复合的赋值运算符以及+和和-,不一定非要定义为成员函数,但最好定义为成员函数,不一定非

15、要定义为成员函数,但最好定义为成员函数。v具有两个运算对象的运算符最好重载为全局函数,这样具有两个运算对象的运算符最好重载为全局函数,这样可以使得应用更加灵活。如果把加运算定义成全局函数可以使得应用更加灵活。如果把加运算定义成全局函数,r是有理数类的对象,则是有理数类的对象,则2+r是一个合法的表达式。是一个合法的表达式。程序设计 cs.sjtu 2011.9程序设计 - 18v什么是运算符重载什么是运算符重载 v运算符重载的方法运算符重载的方法 v几个特殊的运算符的重载几个特殊的运算符的重载 v自定义类型转换运算符自定义类型转换运算符v运算符重载实例运算符重载实例 程序设计 cs.sjtu

16、2011.9程序设计 - 19v赋值运算符赋值运算符 v下标运算符下标运算符v函数调用运算符函数调用运算符 v+和和运算符的重载运算符的重载 v重载函数的原型设计考虑重载函数的原型设计考虑v输入输出运算符重载输入输出运算符重载 程序设计 cs.sjtu 2011.9程序设计 - 20v对任一类,如果用户没有自定义赋值运算对任一类,如果用户没有自定义赋值运算符函数,那么系统为其生成一个缺省的赋符函数,那么系统为其生成一个缺省的赋值运算符函数,在对应的数据成员间赋值值运算符函数,在对应的数据成员间赋值。v一般情况下,这个缺省的赋值运算符重载一般情况下,这个缺省的赋值运算符重载函数能满足用户的需求。

17、但是,当类含有函数能满足用户的需求。但是,当类含有类型为指针的数据成员时,可能会带来一类型为指针的数据成员时,可能会带来一些麻烦。些麻烦。 程序设计 cs.sjtu 2011.9程序设计 - 21v会引起内存泄漏会引起内存泄漏v使这两个数组的元素存放于同一块空间中使这两个数组的元素存放于同一块空间中v当这两个对象析构时,先析构的对象会释当这两个对象析构时,先析构的对象会释放存储数组元素的空间。而当后一个对象放存储数组元素的空间。而当后一个对象析构时,无法释放存放数组元素的空间析构时,无法释放存放数组元素的空间程序设计 cs.sjtu 2011.9程序设计 - 22v赋值运算符只能重载成成员函数

18、赋值运算符只能重载成成员函数v函数原型:函数原型: x &x:operator=(const x &source) / 赋值过程赋值过程 一旦创建了对象一旦创建了对象x1, x2, 可以用可以用 x1 = x2赋值。赋值。程序设计 cs.sjtu 2011.9程序设计 - 23doublearray &doublearray:operator= (const doublearray &right) if (this = &right) return *this; delete storage; low = right.low; high = right.high; storage = new

19、doublehigh - low + 1; for (int i=0; i = high - low; +i) storagei = right.storagei; /复制数组元素复制数组元素 return *this; 程序设计 cs.sjtu 2011.9程序设计 - 24v一般来讲,需要自定义拷贝构造函数的类也需要一般来讲,需要自定义拷贝构造函数的类也需要自定义赋值运算符重载函数。自定义赋值运算符重载函数。v在赋值运算符重载函数中,已经将参数的值赋值在赋值运算符重载函数中,已经将参数的值赋值给了当前对象,那为什么还需要返回值呢?记住给了当前对象,那为什么还需要返回值呢?记住,在,在c+中

20、,赋值是一个运算,它可以形成一个中,赋值是一个运算,它可以形成一个表达式,而该表达式的结果值就是赋给左边的对表达式,而该表达式的结果值就是赋给左边的对象的值。因此,赋值运算符重载函数必须返回赋象的值。因此,赋值运算符重载函数必须返回赋给左边的对象值。给左边的对象值。程序设计 cs.sjtu 2011.9程序设计 - 25v一般来讲,需要拷贝构造函数的类也需一般来讲,需要拷贝构造函数的类也需要重载赋值运算符要重载赋值运算符v定义对象时给对象赋初值调用的是拷贝定义对象时给对象赋初值调用的是拷贝构造函数构造函数v程序的语句部分中的赋值语句调用的是程序的语句部分中的赋值语句调用的是赋值运算符重载函数赋

21、值运算符重载函数程序设计 cs.sjtu 2011.9程序设计 - 26v赋值运算符赋值运算符 v下标运算符下标运算符v函数调用运算符函数调用运算符 v+和和运算符的重载运算符的重载 v重载函数的原型设计考虑重载函数的原型设计考虑v输入输出运算符重载输入输出运算符重载 程序设计 cs.sjtu 2011.9程序设计 - 27v能否象普通的数组那样通过下标运算操作能否象普通的数组那样通过下标运算操作doublearray类的对象,这样可以使类的对象,这样可以使doublearray类更像一个功能内置的数组。类更像一个功能内置的数组。v可以通过重载下标运算符(可以通过重载下标运算符()来实现)来实

22、现 v下标运算符是二元运算符,第一个运算数是下标运算符是二元运算符,第一个运算数是数组名,第二个运算数是下标值数组名,第二个运算数是下标值v下标运算符必须重载成成员函数下标运算符必须重载成成员函数程序设计 cs.sjtu 2011.9程序设计 - 28double & doublearray:operator(int index) if (index high) cout 下标越界下标越界; exit(-1); return storageindex - low; 程序设计 cs.sjtu 2011.9程序设计 - 29v定义:定义:doublearray array(20, 30);v数组输

23、入:数组输入: for (i=20; i=30; +i) cout 请输入第请输入第 i arrayi; v数组输出:数组输出: for (i=20; i=30; +i) cout arrayi end | start high ) cout 下标越界下标越界; exit(-1); doublearray tmp(lh, lh + end - start); for (int i = 0; i end - start + 1; +i) tmp.storagei = storagestart + i - low;return tmp; 程序设计 cs.sjtu 2011.9程序设计 - 35v赋

24、值运算符赋值运算符 v下标运算符下标运算符v函数调用运算符函数调用运算符 v+和和运算符的重载运算符的重载 v重载函数的原型设计考虑重载函数的原型设计考虑v输入输出运算符重载输入输出运算符重载 程序设计 cs.sjtu 2011.9程序设计 - 36v、- - -:是一元操作符:是一元操作符v这两个操作符可以是前缀,也可以是后这两个操作符可以是前缀,也可以是后缀。而且前缀和后缀的含义是有区别的缀。而且前缀和后缀的含义是有区别的。所以,必须有两个重载函数。所以,必须有两个重载函数。 v问题:两个重载函数有相同的原型问题:两个重载函数有相同的原型v区分方法:区分方法: 前缀:一元操作符。前缀:一元

25、操作符。 后缀:二元操作符。后缀:二元操作符。程序设计 cs.sjtu 2011.9程序设计 - 37v成员函数重载成员函数重载 +ob重载为:重载为:ob.operator+() ob- 重载为:重载为:ob.operator-(int)v友元函数重载友元函数重载 +ob重载为:重载为:operator+(x &ob) ob-重载为:重载为:operator-(x &ob, int)v调用时,参数调用时,参数int一般传递给值一般传递给值0。程序设计 cs.sjtu 2011.9程序设计 - 38v设计一个会报警的计数器类。该计数器设计一个会报警的计数器类。该计数器从从0开始计数,当到达预先

26、设定好的报开始计数,当到达预先设定好的报警值时,计数器会发出报警消息,计数警值时,计数器会发出报警消息,计数器的值不再增加。器的值不再增加。 程序设计 cs.sjtu 2011.9程序设计 - 39class counter int value; /计数器的值计数器的值int alarm; /报警值报警值public:counter(int a) value = 0; alarm = a;counter & operator+(); /前缀的前缀的+重载重载counter operator+(int); /后缀的后缀的+重载重载void print() cout value endl; ; 程

27、序设计 cs.sjtu 2011.9程序设计 - 40counter & counter:operator+() if (value = alarm) cout 已超过报警值已超过报警值n; else +value; if (value = alarm) cout 已到达报警值已到达报警值n; return *this;counter counter:operator+(int x) counter tmp = *this; /保存对象修改前的状态保存对象修改前的状态 if (value = alarm) cout 已超过报警值已超过报警值n; else +value; if (value =

28、 alarm) cout )()和流提取运算符和流提取运算符()()输入和输出用户自定输入和输出用户自定义类的对象义类的对象程序设计 cs.sjtu 2011.9程序设计 - 48ostream & operator(ostream & os, const classtype &obj) os 要输出的内容;要输出的内容; return os; 程序设计 cs.sjtu 2011.9程序设计 - 49ostream& operator(ostream &os, const rational& obj) / 输出重载函数输出重载函数 os obj.num / obj.den; return os

29、;如定义:如定义:rational r(2,6);执行执行cout )()和流提取运算符和流提取运算符()(istream & is, classtype &obj) is 要输入的内容;要输入的内容; return is; 程序设计 cs.sjtu 2011.9程序设计 - 52istream& operator(istream &in, rational& obj) / 输入重载函数输入重载函数 in obj.num obj.den; obj.reductfraction(); return in;如定义:如定义:rational r;可以用可以用cin r 从键盘输入从键盘输入r的数据。

30、如输入为:的数据。如输入为:1 3执行执行cout (istream &in, rational& obj); friend ostream& operator(ostream &os, const rational& obj); friend rational operator+(const rational &r1, const rational &r2); friend rational operator*(const rational &r1, const rational &r2); private: int num;int den;void reductfraction();pub

31、lic:rational(int n = 0, int d = 1) num = n; den = d;operator double () const return (double(num)/den); 程序设计 cs.sjtu 2011.9程序设计 - 63#include #include rational.hint main() rational r1, r2, r3, r4; double x; cout r1; cout r2; r3 = r1 + r2; cout r1 + r2 = r3 endl; r3 = r1 * r2; cout r1 * r2 = r3 endl; r

32、4 = (r1 + r2) * r3; cout (r1 + r2) * r3的值为:的值为: r4 endl; x = 5.5 - r1; cout 5.5 - r1的值为:的值为: x endl; cout (r1 r2 ? r1 : r2) endl; return 0; 输入输入r1: 1 3输入输入r2: 2 61/3+1/3 = 2/31/3*1/3 = 1/9(r1 + r2) * r3的值为的值为2/275.5 - r1的值为:的值为:5.166671/3 程序设计 cs.sjtu 2011.9程序设计 - 64v什么是运算符重载什么是运算符重载 v运算符重载的方法运算符重载的

33、方法 v几个特殊的运算符的重载几个特殊的运算符的重载 v自定义类型转换运算符自定义类型转换运算符 v运算符重载实例运算符重载实例程序设计 cs.sjtu 2011.9程序设计 - 65v完善完善doublearray类类程序设计 cs.sjtu 2011.9程序设计 - 66#ifndef _array_h#define _array_h#include class doublearrayfriend ostream &operator(istream &is, doublearray &obj);friend bool operator=(const doublearray &obj1, c

34、onst doublearray &obj2);private: int low; int high; double *storage;程序设计 cs.sjtu 2011.9程序设计 - 67public: doublearray(int lh = 0, int rh = 0):low(lh), high(rh) storage = new double high - low + 1; doublearray(const doublearray &arr); doublearray &operator=(const doublearray &right); double & operator(

35、int index); const double & operator(int index) const; doublearray operator()(int start, int end, int lh); doublearray() delete storage; ;#endif程序设计 cs.sjtu 2011.9程序设计 - 68/文件名:文件名:doublearray.cpp/doublearray类的实现类的实现#include #include doublearray.h“doublearray:doublearray(const doublearray &arr) low =

36、 arr.low; high = arr.high; storage = new double high - low + 1; for (int i = 0; i high -low + 1; +i) storagei = arr.storagei;程序设计 cs.sjtu 2011.9程序设计 - 69doublearray &doublearray:operator= (const doublearray & a) if (this = &a) return *this; delete storage; low = a.low; high = a.high; storage = new d

37、oublehigh - low + 1; for (int i=0; i = low & index = low & index = high); return storageindex - low; 程序设计 cs.sjtu 2011.9程序设计 - 71ostream &operator(ostream &os, const doublearray &obj) os 数组内容为:数组内容为:n; for (int i=obj.low; i=obj.high; +i) os obji t; os ( istream &is, doublearray &obj) cout 请输入数组元素请输入数组元素 obj.low , obj.high :n; for (int i=obj.low; i obji ; r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论