第9章运算符重载

上传人:pu****.1 文档编号:585817782 上传时间:2024-09-03 格式:PPT 页数:37 大小:529.50KB
返回 下载 相关 举报
第9章运算符重载_第1页
第1页 / 共37页
第9章运算符重载_第2页
第2页 / 共37页
第9章运算符重载_第3页
第3页 / 共37页
第9章运算符重载_第4页
第4页 / 共37页
第9章运算符重载_第5页
第5页 / 共37页
点击查看更多>>
资源描述

《第9章运算符重载》由会员分享,可在线阅读,更多相关《第9章运算符重载(37页珍藏版)》请在金锄头文库上搜索。

1、第第9章运算符重载章运算符重载目目 录录91 运算符重载概述运算符重载概述93 双目运算符重载双目运算符重载94 比较运算符重载比较运算符重载95 赋值运算符重载赋值运算符重载问题引入:问题引入:#include class Complexpublic:Complex() real=0.0; imag=0.0; Complex(double r, double i) real=r; imag=i;void display() coutreal“+”image“i”endl;private:double real;double imag;Complex a(10,20),b(5,8),c;c=a

2、+b?91 运算符重载概述运算符重载概述c+中预定义的运算符的操作对象只能是中预定义的运算符的操作对象只能是基本基本数据类型数据类型很多用户自定义类型(比如类),也需要有类很多用户自定义类型(比如类),也需要有类似的运算操作,这就提出了对运算符进行重新似的运算操作,这就提出了对运算符进行重新定义,赋予已有符号以新功能的要求。定义,赋予已有符号以新功能的要求。运算符重载是对已有的运算符赋予多重含义,运算符重载是对已有的运算符赋予多重含义,同一个运算符作用于不同类型的数据导致不同同一个运算符作用于不同类型的数据导致不同类型的行为。类型的行为。 返回目录运算符重载的实质就是函数重载。运算符重载的实质

3、就是函数重载。91 运算符重载概述运算符重载概述!+-*&/%= =!=|&+=-=*=/=%=&=|=,-*-()=+-newdelete表表9.1 C+9.1 C+中可以重载的运算符中可以重载的运算符表表92 C+中不能重载的运算符中不能重载的运算符.*:?: 返回目录91 运算符重载概述运算符重载概述运算符重载的规则如下:运算符重载的规则如下:1.C+中的运算符除了少数几个之外,全部可以重载,中的运算符除了少数几个之外,全部可以重载,而且而且只能重载已有的这些运算符只能重载已有的这些运算符。2.重载之后运算符的重载之后运算符的优先级和结合性都不会改变优先级和结合性都不会改变。3.重载不能

4、改变原运算符的重载不能改变原运算符的操作对象个数操作对象个数,同时,同时至至少要有一个操作对象是自定义类型少要有一个操作对象是自定义类型。4.一般来讲,重载的一般来讲,重载的功能应当与原有功能相类似功能应当与原有功能相类似。 返回目录91 运算符重载概述运算符重载概述friend 函数类型函数类型 operator 运算符运算符(形参表形参表)当重载为当重载为类的友元函数类的友元函数时,参数个数时,参数个数与原运算数的个数相同。与原运算数的个数相同。函数类型函数类型 operator 运算符运算符(形参表形参表) 当运算符重载为当运算符重载为类的成员函数类的成员函数时,函数的参数个数比原来的运

5、时,函数的参数个数比原来的运算数个数要少一个算数个数要少一个(后缀后缀+、-除外除外);运算符的重载形式有两种:运算符的重载形式有两种:重载为类的友元函数重载为类的友元函数重载为类的成员函数重载为类的成员函数 返回目录91 运算符重载概述运算符重载概述#include class Complexpublic:Complex() real=0.0; imag=0.0; Complex(double r=0.0, double i=0.0) real=r; imag=i;void display() coutreal“+”image“i”endl;Complex operator+ (const

6、complex &s1); private:double real;double imag;friend Complex operator+ (const Complex &s1,const Complex &s2);91 运算符重载概述运算符重载概述在编译执行过程中,首先把指定的表达式转化为对运算符函在编译执行过程中,首先把指定的表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用的函数。参的类型来确定需要调用的函数。Complex a(2,3),b(4,5),c;c=a+b;c=operator

7、+(a,b); c=a.operator+(b); 双目运算符双目运算符 + - * / % = .可重载为:可重载为:成员函数:非静态,一个参数成员函数:非静态,一个参数非成员函数:两个参数非成员函数:两个参数单目运算符单目运算符 + + - - !- *.可重载为:可重载为:成员函数成员函数: 非静态,没有参数非静态,没有参数非成员函数:一个参数的非成员函数:一个参数的一些一些必须重载为类的成员函数必须重载为类的成员函数的运算符的运算符( ), , -,=只能重载为只能重载为非成员函数非成员函数的情况的情况:你自定义的类是第二个操作数你自定义的类是第二个操作数91 运算符重载概述(完)运算

8、符重载概述(完) 返回目录最好这样做最好这样做93 双目运算符重载双目运算符重载1.双目运算符重载为类的成员函数双目运算符重载为类的成员函数 返回目录oprd1 B oprd2class Complexpublic: Complex() real=0.0; imag=0.0; Complex(double r, double i) real=r; imag=i;void display() coutreal+imagiendl;Complex operator + (const Complex &s1);Complex operator (const Complex &s1);private:

9、double real;double imag;93 双目运算符重载双目运算符重载 返回目录Complex Complex:operator + (const Complex & s1)Complex s;s.real=real+s1.real;s.imag=imag+s1.imag;return s;Complex Complex:operator - (const Complex & s1)Complex s;s.real=real - s1.real;s.imag=imag - s1.imag;return s;对象本身是左对象本身是左操作数,右操操作数,右操作数为参数作数为参数93 双

10、目运算符重载双目运算符重载void main()Complex v1(6,8),v2(3,6),v3,v4;cout v1=;v1.display();cout v2=;v2.display();v3=v1+v2; /v3=v1.operator+(v2);cout v1+v2=; v3.display();v4=v1-v2; /v4=v1.operator-(v2);cout v1-v2=; v4.display(); 返回目录 v1=68i v2=36i v1+v2=914i v1-v2=32i93 双目运算符重载双目运算符重载2.双目运算符重载为类的友元函数双目运算符重载为类的友元函数

11、返回目录class Complexpublic:Complex() real=0.0; imag=0.0; Complex(double r, double i) real=r; imag=i;void display() coutreal+imagiendl;private:double real;double imag;friend Complex operator+(const Complex &s1,const Complex &s2);friend Complex operator- (const Complex &s1,const Complex &s2);93 双目运算符重载双目

12、运算符重载Complex operator + (const Complex &s1,const Complex &s2)Complex s;s.real=s1.real+s2.real;s.imag=s1.imag+s2.imag;return s;Complex operator - (const Complex &s1,const Complex &s2)Complex s;s.real=s1.real - s2.real;s.imag=s1.imag - s2.imag;return s; 返回目录第一个参数为左操第一个参数为左操作数,第二个参数作数,第二个参数为右操作数为右操作数93

13、 双目运算符重载(完)双目运算符重载(完)void main()Complex v1(6,8),v2(3,6),v3,v4;cout v1=;v1.display();cout v2=;v2.display();v3=v1+v2; /v3=operator+(v1,v2);cout v1+v2=;v3.display();v4=v1-v2; /v4=operator+(v1,v2);cout 、或或=)的重载函数。的重载函数。比较运算符重载函数必须返回真比较运算符重载函数必须返回真(true/非非0)或假或假(false/0)。 返回目录class Complexpublic:Complex(

14、) real=0.0; imag=0.0; Complex(double r, double i) real=r; imag=i;void display() coutreal+imagiendl;Complex operator+(const Complex &s1);Complex operator - (const Complex &s1);bool operator = = (const Complex &s1);bool operator != (const Complex &s1);private:double real;double imag;94 比较运算符重载比较运算符重载b

15、ool Complex :operator =(const Complex &s1)if(real=s1.real)&(imag=s1.imag)return true;elsereturn false;bool Complex :operator !=(const Complex &s1)if(real!=s1.real)|(imag!=s1.imag)return true;elsereurn false;return !(*this= =s1);94 比较运算符重载比较运算符重载(完完)void main()Complex a(3,4),b(5,6),c(8,10);if( (a+b)=

16、c)cout“相等相等!”endl;elsecout“不等不等”endl; ( a.operator+(b) ) .operator= =(c) 95 赋值运算符重载赋值运算符重载在在C+中有两种类型的赋值运算符:中有两种类型的赋值运算符: 、.适于实现为类的成员函数适于实现为类的成员函数 返回目录951 运算符运算符“=”的重载的重载赋值运算符赋值运算符“=”的原有含义是将赋值号右的原有含义是将赋值号右边表达式的结果边表达式的结果拷贝拷贝给赋值号左边的变量。给赋值号左边的变量。为了保证同类对象之间能够进行赋值操作,为了保证同类对象之间能够进行赋值操作,每个类应定义赋值操作每个类应定义赋值操作

17、(重载运算符)。(重载运算符)。如果程序中没有定义赋值操作,则如果程序中没有定义赋值操作,则c编译编译器器自动生成自动生成,实现将赋值号右边对象的数据,实现将赋值号右边对象的数据成员依次拷贝到赋值号左边对象的数据成员成员依次拷贝到赋值号左边对象的数据成员中。中。class Complexpublic:Complex() real=0.0; imag=0.0; Complex(double r, double i) real=r; imag=i;Complex(const Complex &s) real=s.real; imag=s.imag; void display() coutreal+

18、imagiendl;complex operator+(const complex &s1);complex operator- (const complex &s1);bool operator = (const complex &s1);bool operator != (const complex &s1);Complex& operator = (const Complex &s1);private:double real;double imag;Complex& Complex :operator = (const Complex &s1)real= s1.real; imag =

19、s1.imag;return *this;void main()Complex a(2,3);Complex b=a;Complex c,d;d=c=a;952 运算符运算符“+=”和和“-=”的重载的重载 对于标准数据类型,对于标准数据类型, “+=”和和“-=”的的作用是将一个数据与另一个数据进行加法作用是将一个数据与另一个数据进行加法或减法运算后再将结果回送给赋值号左边或减法运算后再将结果回送给赋值号左边的变量中。的变量中。a+=ba=a+bclass Complexpublic:Complex() real=0.0; imag=0.0; Complex(double r=0.0, do

20、uble i=0.0) real=r; imag=i;Complex(const Complex &s) real=s.real; imag=s.imag; void display() coutreal+imagiendl;Complex operator+(const Complex &s1);Complex operator -(const Complex &s1);bool operator = = (const Complex &s1);bool operator != (const Complex &s1);Complex& operator = (const Complex &s

21、1);Complex& operator -= (const Complex &s1);private:double real;double imag;friend Complex& operator+=(Complex &s1,const Complex &s2);Complex& Complex:operator -=(const Complex &s1)real -= s1.real;imag -= s1.imag;return *this;Complex& operator+= (Complex &s1, const Complex &s2)s1.real+= s2.real;s1.i

22、mag+= s2.imag;return s1;void main ()complex s1(3,4),s2(5,6),s3;s3+=s1;s3-=s1;这两个成员函数必须有,若没有,系统自动这两个成员函数必须有,若没有,系统自动为类创建,提供缺省实现。为类创建,提供缺省实现。什么时候不使用使用缺省实现?什么时候不使用使用缺省实现?1. 不不需要需要拷贝所有拷贝所有的数据成员。的数据成员。2.要要做其他的事情。做其他的事情。3.数据成员中数据成员中有指针类型时有指针类型时(默认的实现的是(默认的实现的是浅拷贝,浅拷贝会带来安全上的隐患)浅拷贝,浅拷贝会带来安全上的隐患)探讨:探讨:拷贝构造函数

23、拷贝构造函数和和=运算符重载函数运算符重载函数浅拷贝带来的悬挂指针问题浅拷贝带来的悬挂指针问题class Mpublic:M(int i);M();void print();private:int *p;M:M(int i)p = new int(i);M:M()delete p;编译器自动生成:编译器自动生成:M:M(const M &m):p(m.p) M& M:operator=(const M &m)p=m.p;return *this;5aM a(5),b(a);b5aM a(5),b(7);7bb = a 5a7b浅拷贝带来的悬挂指针问题浅拷贝带来的悬挂指针问题自己定义(深拷贝)自

24、己定义(深拷贝)M:M(const M &m)p=new int ;*p=*(m.p);M& M:operator=(const M &m)*p=*(m.p);return *this;5aM a(5),b(7);7ba = b7a7b5aM a(5),b(a);b5编译器自动生成:编译器自动生成:M:M(const M &m):p(m.p) M& M:operator=(const M &m)p=m.p;return *this;例:用例:用char*表示姓名表示姓名class Studentint no; int grade;char *name;Student()name=NULL;St

25、udent(int n,int g,char * na)no=n;grade=g;name=new charstrlen(na)+1;strcpy(name,na);Student()delete name;必须自己写必须自己写拷贝构造函数拷贝构造函数和和=自动生成自动生成Student(const Student &s)no=s.no;grade=s.grade;name=s.name;自定义自定义Student(const Student &s)no=s.no;grade=s.grade;name=new charstrlen(s.name)+1;strcpy(name,s.name);自

26、动生成自动生成Student & operator=(const Student &s)no=s.no;grade=s.grade;name=s.name;return *this;自定义自定义Student & operator=(const Student &s)no=s.no;grade=s.grade;if(this!=&s)delete name;name=new charstrlen(s.name)+1;strcpy(name,s.name);return *this;例:例:定义一个整型数组类定义一个整型数组类class Arrayprivate:int *ptr;int siz

27、e;public:Array(int arraySize=10);Array(int ,int );Array(const Array&);Array &operator = (const Array &);Array() delete ptr;int getSize()const return size;void set(int i,int g)ptri=g;int get(int i)return ptri;能创建特定大小的数组能创建特定大小的数组能用一个系统数组初始能用一个系统数组初始化你的数组化你的数组能用同类型的其他数组能用同类型的其他数组初始化你的数组初始化你的数组两个数组可以互相

28、赋值两个数组可以互相赋值Array:Array(int arraySize)size=arraySize;ptr=new int size;for(int i=0;isize;i+)ptri=0;Array:Array(int a ,int s)size=s;ptr=new intsize;for(int i=0;isize;i+)ptri=ai;Array:Array(const Array &init)size=init.size;ptr=new intsize;for(int i=0;isize;i+)ptri=init.ptri;Array& Array:operator =(cons

29、t Array &right)if(&right!=this)delete ptr;size=right.size;ptr=new intsize;for(int i=0;isize;i+)ptri=right.ptri;return *this;92 单目运算符重载单目运算符重载 “+”、“-”运算符有前缀和后缀两种使用形式运算符有前缀和后缀两种使用形式重载运算符也有前缀和后缀两种运算符重载形式重载运算符也有前缀和后缀两种运算符重载形式以以“+”重载运算符为例,其语法格式如下:重载运算符为例,其语法格式如下: 返回目录 函数类型函数类型 operator +( ); /前缀运算前缀运算 函数

30、类型函数类型 operator +(int); /后缀运算后缀运算 使用前缀运算符的语法格式如下:使用前缀运算符的语法格式如下: +对象对象;使用后缀运算符的语法格式如下:使用后缀运算符的语法格式如下: 对象对象+; 例例9.1,9.2#include class Samplepublic:Sample(int i) :n(i) void operator +( ) n+=1; /前缀运算符前缀运算符void operator +(int) n+=2; /后缀运算符后缀运算符void display()cout n= n endl;private:int n;void main()Sample

31、 a(5), b(5); +b; b.display(); /调用前缀运算符重载调用前缀运算符重载a+; a.display(); /调用后缀运算符重载调用后缀运算符重载 返回目录n=7n=6缺陷:缺陷:Sample a,b(5);a=+b; /错误错误#include class Countpublic:Count(int i=0): n(i)Count& operator +() +n;return *this;Count operator+(int)Sample temp = *this;+n;return temp;private:int n;return Count(n+);Sample a(4), b(0);b=a+;/b.n为为4b=+a;/b.n为为6

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号