c课件运算符重载和类重载.ppt_第1页
c课件运算符重载和类重载.ppt_第2页
c课件运算符重载和类重载.ppt_第3页
c课件运算符重载和类重载.ppt_第4页
c课件运算符重载和类重载.ppt_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

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

文档简介

第12章 运算符重载和类型重载 主要内容: 12.1 运算符重载规则 12.2 类型重载 在C+中有这样的情况,同一个类型或运算符在不同的 类中代表不同的意思或者实施不同的运算,这就是面向对象 的三大特点之一的多态。 函数重载是C+语言中多态的一种表现形式,运算符重 载和类型重载是多态的另外两种表现形式。 运算符重载是对已有的运算符赋予多重含义。 C+中预定义的运算符的操作对象只能是基本数据类型 ,对于很多用户自定义类型,也需要有类似的运算操作, 这就提出了对运算符进行重新定义,赋予已有符号以新功 能的要求。 同一个运算符作用于不同类型的数据导致不同的行为。 12.1 运算符重载概述 运算符重载只能对系统提供的已有运算定义新的运算 含义,不能创造全新的运算符,同时还不能改变运算符原 有的语法结构、操作数个数、优先级和结合性,不能有二 义性。不是所有的运算符都能重载,不能重载的运算符有 :作用域运算符(:)、条件运算符(?:)、直接成员访 问运算符(.)、sizeof运算符、解除对指向类成员的指针 的引用运算符(.*)。 运算符重载的关键字是operator。针对一个具体类的已 有运算符重载有两种途径: 1)将运算符重新定义为类的成员函数; 2)将运算符重新定义为类的友元函数。 一、运算符重载方法 定义一个重载运算符就像定义一个函数,只是该函数的 名字是operator,这里代表运算符。函数参数表中参数的 个数取决于两个因素: 1) 运算符是一元的(一个参数)还是二元的(两个参 数)。 2) 运算符被定义为友元函数(对于一元是一个参数, 对于二元是两个参数)还是成员函数(对于一元没有参数, 对于二元是一个参数对象变为左侧参数)。 1.将运算符重载为类的成员函数 将运算符重载为类的成员函数就是在类中用关键字operator 定义一个成员函数,函数名就是重载的运算符。运算符如果重 载为类的成员函数,它就可以自由地访问该类的数据成员。 运算符重载为类的成员函数的一般格式为: : operator (形参表) 函数体 其中,类型为运算符重载函数的返回类型。类名为成员函数 所属类的类名,即为重载函数名。形 参为参加运算的对象或数据。 【例题12.1】 复数的加减运算符重载 #include using namespace std; class Complex private: float real,image; public: Complex(float r=0,float i=0); Complex Add(const Complex /定义一个Add函数 Complex operator+(const Complex /重载+运算符 Complex operator-(const Complex /重载-运算符 Complex /重载+=运算符,复合赋值操作 符必须返回左操作数的引用,必须定义为成员函数 Complex /重载=运算符,赋值运算符 必须返回对*this的引用, void Show(int i); ; Complex:Complex(float r,float i) real=r; image=i; void Complex:Show(int i) /一般情况下,这里不应该有参数i,本例的目的是为了区分不同的 复数,便于观看结果 cout0) coutreal+c.real; t.image=this-image+c.image; return t; Complex Complex:operator+(const Complex t.real=this-real+c.real; t.image=this-image+c.image; return t; Complex Complex:operator-(const Complex t.real=this-real-c.real; t.image=this-image-c.image; return t; Complex image=image+c.image; return *this; Complex this-real=other.real; this-image=other.image; return *this; int main() Complex c1(12,35),c2(20,46),c3,c4,c5,c6; c1.Show(1); c2.Show(2); c3=c1.Add(c2); c3.Show(3); c4=c1+c2; c4.Show(4); c2+=c1; c2.Show(2); c5=c1-c2; c5.Show(5); return 0; 如果我们把“operator+”看成函数名,可以在main()函数 中写出如下语句: c3=c1.Add(c2); c3=c1.operator+(c2); 这时,operator+就完全是一个函数了(它本质上就是函数 ),.Add()和operator+的作用和功能完全相同,只是表现形式有 些区别。 【例题12.2】一元运算符重载,在Time类(描述时间的类,用三个数 据成员分别存放时、分和秒)中重载自加运算符,即一个时间加上n 秒后形成一个新的的时间。 class Time private: int hour,minute,second; public: Time(int h=0,int m=0,int s=0); /其他构造函数省略 如Time(Time void Show();/显示时:分:秒的成员函数 Time /定义前置+运算符重载成员函数 Time operator+(int);/定义后置+运算符重载成员函数 Time /重载=运算符 ; Time:Time(int h,int m,int s) hour=h; minute=m; second=s; void Time:Show() couthour=other.hour; this- minute =other. minute; this- second =other. second; return *this; int main() Time t1(10,25,52),t2,t3; t1.Show(); t2=+t1; t1.Show(); t2.Show(); t3=t1+; t3.Show(); t1.Show(); 对于+(或-)运算符的重载, 因为编译器不能区分出+(或-)是 前置的还是后置的,所以要加上(int) 来区分。 operator+(); /重载前置+ operator+(int); /重载后置+ operator-(); /重载前置- operator-(int); /重载后置- 运算符重载的一些特点如下: (1) 运算符重载函数名必须为:operator。 (2) 运算符的重载是通过运算符重载函数来实现的。 对于二元运算符重载函数,函数的参数通常为一个 即右操作数,运算符的左操作数为调用重载函数的 对象。对于一元运算符重载函数,运算符的左操作 数或右操作数为调用重载函数的对象。 (3) 运算符重载函数的返回类型:若对象进行运算后 的结果类型仍为原类型,则运算符重载函数的返回 类型应为原类型。 【例11.3】 自定义字符串类String中有一个private成 员p_str指向一个C格式的字符串,写出其拷贝构造函数 ,并重载赋值“=”运算符。 #include #include using namespace std; class String public: String()p_str=NULL; String(const String String(const char*str); String()delete p_str; String private: char *p_str; ; String:String(const char *str) p_str=new charstrlen(str)+1; strcpy(p_str,str); String:String(const String 一元运算符重载为友元函数的一般格式为: operator (类名 class Complex private: float real,image; public: Complex(float r=0,float i=0); friend Complex operator+( const Complex friend Complex operator-( const Complex void Show(int i); ; Complex:Complex(float r,float i) real=r; image=i; void Complex:Show(int i) cout0) cout using namespace std; class Complex private: float real,image; public: Complex(float r=0,float i=0); Complex operator+(const Complex Complex operator+(const int k); Complex operator+(const float f); void Show(int i); ; int main() Complex c1(12,35),c2(20,46),c3,c4,c5,c6; int i=5; float f=7.7; c1.Show(1); c2.Show(2); c3=c1+i; /编译正确 c3.Show(3); c4=c1+f; /编译正确 c4.Show(4); c5=c1+1.5; /编译错误,可用c5=c1+(int)1.5;或者 c5=c1+(float)1.5; c5.Show(5); return 0; 在进行运算符重载时,我们要注意: 1)重载不能改变该运算符用于内置类型时的含义,正如程序 员不能改变运算符+用于两个int型相加时的含义。 2)运算符函数的参数至少有一个必须是类的对象或者类的对 象的引用,这种规定可以防止程序员运用运算符改变内置 类型的函义。 3)重载不能改变运算符的优先级。 4)重载不能改变运算符的结合律。 5)重载不能改变运算符操作数的个数。比如+需要两个操作数 ,则重载的+也必须要有两个操作数。 6)不存在用户定义的运算符,即不能编写目前运算符集合中 没有的运算符。不能这样做的部分原因是难以决定其优先 级,另一部分原因是没有必要增加麻烦。 当一个重载操作符的含义不明显时,给操作取一个名字 更好。对于很少用的操作,使用命名函数通常比用操作符更 好。如果不是普通操作,没必要为简洁而使用操作符。 重载逗号、取地址、逻辑与、逻辑或等操作符通常不是 好做法。这些操作符具有有用的内置含义,如果我们定义了 自己的版本,就不能再使用这些内置含义。 如果类定义了相等操作符,也应该定义不等操作符!=。 同样,如果定义了, =,)等 操作符必须定义为成员,将这些操作符定义为非成员函数在编译时标 记为错误。 2)像赋值一样,复合赋值操作符通常应定义为类的成员函数。定义 成非成员函数不会出现编译错误。 3)改变对象状态或与给定类型紧密联系的其他一些操作符,如自增 、自减等通常定义为类成员函数。 4)对称的操作符,如算术操作符、相等操作符、关系操作符和位操 作符,最好定义为非成员函数。 istream 和 ostream 是 C+ 的预定义流类,cin 是 istream 的对象,cout 是 ostream 的对象。运算符 由 istream 重载 为提取操作, 用于输出和输入基本类型数据。可用重载 运算符 ,用于输出和输入用户自定义的数据类型 ,必须定义为类的友元函数。 4. 重载流插入和流提取运算符 1)输出操作符 using namespace std; class Date public: Date(int y,int m,int d); bool isLeapYear(); void print(); friend ostream Date:Date(int y,int m,int d) year=y; month=m; day=d; bool Date:isLeapYear() return (year%4=0 void Date:print() cout #include “Date.h“ using namespace std; int main() Date d1(2013,4,1); cout的重载 输入操作符重载函数形式为: istream 与输出操作符类似,输入操作符的第一个形参是一个 引用,指向要读的流,并且返回的也是同一个流的引用 。第二个形参是对要读入的对象的非const 引用,该形 参必须为非const,因为输入操作符的目的是将数据读到 这个对象中。和输出操作符不同的是输入操作符必须处 理错误和文件结束的可能性。 【例题11.8】重载输入操作符,在上例的基础上加上Date类对象能 用“”输入数据。 class Date public: Date()year=0;month=0;day=0; Date(int y,int m,int d

温馨提示

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

评论

0/150

提交评论