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

下载本文档

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

文档简介

第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介运算符重载使得系统的内置运算符适用于类的对象之间的操作。提高程序的可读性。运算符重载使得系统的内置运算符适用于类的对象之间的操作。提高问题的提出希望某些运算符能够对整个对象进行操作,而不是C中的简单操作.例如:+运算符能够实现2个对象间的加。类A的对象a1、a2、a3,希望:a3=a1+a2;

即:分别把对象a1和a2的各个数据成员值对应相加,然后赋给对象a3。问题的提出希望某些运算符能够对整个对象进行操作,而不是C中的问题的提出把某些事交给系统去做,用户只要知道相加就可提出运算符重载,扩充运算符的功能。即:对运算符进行重载定义,然后使用,由系统自动判断究竟采用哪一个具体的运算符。增强了C++语言的可扩充性。问题的提出把某些事交给系统去做,用户只要知道相加就可运算符重载的限制不是所有的运算符都能重载重载不能改变运算符的优先级和结合性重载不能改变运算符的操作数个数不能创建新的运算符不能改变用于内部类型对象时的含义用于用户自定义类型对象,或者和内部类型的对象混合使用运算符重载的限制不是所有的运算符都能重载可以重载的运算符+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

==

!=

<=

>=

&&

||

++

--

->*

->

[]

()

new

delete

new[]

delete[]

.

.*

::

?:

sizeof

不能重载的运算符:可以重载的运算符+

-

运算符重载的实现方法

用普通函数实现用成员函数实现用友元函数实现运算符重载的实现方法用普通函数实现第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介用普通函数实现运算符重载创建运算符函数运算符函数名为:

operator后接一个要重载的运算符。如:要重载“+”运算,函数名为operator+。重载“-”运算,函数名为operator-。参数表为要参加运算的对象,返回值为运算结果用普通函数实现运算符重载创建运算符函数运算符重载函数实例#include<iostream.h>classcomplex{public:intr,i;complex(intrr=0,intii=0){i=ii;r=rr;}};complexoperator+(complexa1,complexa2){complext;t.r=a1.r+a2.r;t.I=a1.i+a2.i;returnt;}voidmain(){complexa1(1,2),a2(3,4),b;b=a1+a2;cout<<b.r<<b.i;}运算符重载函数实例#include<iostream.h>重载成普通函数的缺陷运算符重载通常要对类的私有数据成员作操作。如果用普通函数重载,则需要通过公有的方法访问私有的数据成员,运算速度较慢,或将所有的数据成员都设为公有,直接访问这些数据成员,这样将违反类的封装。重载成普通函数的缺陷运算符重载通常要对类的私有数据成员作操作第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介友元运算符函数把运算符函数定义成某个类的友元函数,称为友元运算符函数。友元函数在类内部的声明

friendtypeoperator@(参数表);友元函数的定义:与一般函数相同typeoperator@(参数表){//函数体}友元运算符函数把运算符函数定义成某个类的友元函数,称为友元运双目运算符重载友元运算符函数必须有两个参数例:二元加操作符重载为友元函数#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}friendAoperator+(constA&a,constA&b);voidshow(){cout<<"x="<<x<<"y="<<y<<endl;}};Aoperator+(constA&a,constA&b){returnA(a.x+b.x,a.y+b.y);}voidmain(){Aa1(5,55),a2(6,66),a3;a3=a1+a2;//调用操作符重载函数:oprator+(a1,a2)a3.show();}x=11y=121双目运算符重载x=11y=121单目运算符重载友元运算符有一个参数例:一元减操作符重载为友元函数#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}

friendAoperator-(constA&a);voidshow(){cout<<"x="<<x<<"y="<<y<<endl;}};Aoperator-(constA&a){returnA(-a.x,-a.y);}voidmain(){Aa1(5,55);a1=-a1;//调用操作符重载函数:operator+(a1)a1.show();}x=-5y=-55单目运算符重载友元运算符有一个参数x=-5y=-55第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介成员运算符函数运算符重载通常作用在一个类上,因此可定义为类的成员函数或友元函数。成员运算符函数的声明classX{//…

typeoperator@(参数表)//…}成员运算符函数的定义

typeX::operator@(参数表){//函数体}成员运算符函数运算符重载通常作用在一个类上,因此可定义为类的双目运算符重载成员运算符只需要一个参数,作为运算符的右操作数,当前对象作为左操作数。例1:二元加操作符重载为成员函数。#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}

Aoperator+(Ab){Atmp; tmp.x=x+b.x;tmp.y=y+b.y;returntmp;}voidshow(){cout<<"x="<<x<<"y="<<y<<endl;}};voidmain(){Aa1(5,55),a2(6,66),a3;a3=a1+a2;//a3=a1.operator+(a2);a3.show();}x=11y=121双目运算符重载成员运算符只需要一个参数,作为运算符的右操作数单目运算符重载成员运算符无参数例:一元减操作符重载为成员函数#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}

Aoperator-(){returnA(-x,-y);}voidshow(){cout<<"x="<<x<<“y="<<y<<endl;}};voidmain(){Aa1(5,55);a1=-a1;//调用操作符重载函数:a1=a1.operator-()a1.show();}/*执行结果:x=-5y=-55*/单目运算符重载成员运算符无参数成员运算符函数与友元运算符函数的比较成员运算符函数比友元运算符函数少一个参数。除=、()、[]、->这4种操作符必须重载成成员函数外,其他操作符重载成友元函数较好。例,a是类A的一个对象,对于表达式:27.5+a对友元函数不存在问题:operator+(A(27.5),a)但是,对成员函数存在问题:(27.5).operator+(a)//非法:27.5不是一个对象,无this指针。成员运算符函数与友元运算符函数的比较成员运算符函数比友元运算成员运算符函数与友元运算符函数的比较cont.成员运算符函数和友元运算符函数都可用习惯方式调用,也可用专用方式调用。习惯方式友元运算符调用方式成员运算符调用方式a+boperator+(a,b)a.operator+(b)-aoperator-(a)a.operator-()成员运算符函数与友元运算符函数的比较cont.成员运算第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介典型的运算符重载++和--的重载=的重载类型转换典型的运算符重载++和--的重载“++”和“--”重载++、--:是一元操作符但是,可以是前缀或后缀。所以,重载时有所不同。区分方法:前缀:一元操作符。后缀:二元操作符。“++”和“--”重载++、--:是一元操作符“++”和“--”重载cont.成员函数重载++ob重载为:ob.operator++()ob--重载为:ob.operator--(int)友元函数重载++ob重载为:operator++(X&ob)ob--重载为:operator--(X&ob,int)调用时,参数int一般传递给值0。“++”和“--”重载cont.成员函数重载++和--操作符重载成成员函数

#include<iostream.h>classCounter{unsignedvalue;public:Counter(intv=0){value=v;}

Counteroperator++(){value++;cout<<"1..."<<value<<"";return*this;}

Counteroperator++(int){Countert;cout<<"2..."<<value<<"";t.value=value++;returnt;}voiddisplay(){cout<<value<<endl;}};voidmain(){Countera(11),b(22),c;++a;//自动调用operator++()a.display();c=b++;//自动调用operator++(int)b.display();c.display();}1...12122...222322*/++和--操作符重载成成员函数#include<iostr++和--操作符重载成友元函数

#include<iostream.h>classCounter{unsignedvalue;public:Counter(intv=0){value=v;}

friendCounteroperator++(Counter&);friendCounteroperator++(Counter&,int);voiddisplay()const{cout<<value<<endl;}};Counteroperator++(Counter&cc){cc.value++;cout<<"1..."<<cc.value<<"";returncc;}Counteroperator++(Counter&cc,int){Countert;cout<<"2..."<<cc.value<<"";t.value=cc.value++;returnt;}voidmain(){Countera(11),b(22),c;

++a;//自动调用operator++(Counter&)a.display();c=b++;//自动调用operator++(Counter&,int)b.display();c.display();}1...12122...222322*/++和--操作符重载成友元函数#include<iostr运算符重载实例试设计一个类,用来表示大于longint的数字设想:用一个由数字组成的字符串来表示数据。如允许的最大长度为128位,则字符数组的长度为128。如数字123,可表示为127126…4321000000123运算符重载实例试设计一个类,用来表示大于longint类的定义classlonglong{chars[128];public:longlong(constchar*s1);longlong(); friendlonglongoperator+(constlonglong&p1,constlonglong&p2); friendlonglongoperator+(constlonglong&p1,constint&p2); friendlonglongoperator+(constint&p2,constlonglong&p1); friendlonglongoperator-(constlonglong&p1,constlonglong&p2); friendlonglongoperator-(constlonglong&p1,constint&p2); friendlonglongoperator-(constint&p2,constlonglong&p1); friendlonglongoperator*(constlonglong&p1,constlonglong&p2); friendlonglongoperator*(constlonglong&p1,constint&p2); friendlonglongoperator*(constint&p2,constlonglong&p1); friendlonglongoperator/(constlonglong&p1,constlonglong&p2); friendlonglongoperator/(constlonglong&p1,constint&p2); friendlonglongoperator%(constlonglong&p1,constlonglong&p2); friendlonglongoperator%(constlonglong&p1,constint&p2); voidshow();};类的定义classlonglong构造函数定义longlong(constchar*s1){inti=strlen(s1)-1,j=0; while(i>=0){if(s1[i]>'9'||s1[i]<'0') {cout<<"seterror";i=-1;} else{s[j]=s1[i];--i;++j;}} for(;j<128;++j)s[j]='0'; }longlong(){for(inti=0;i<128;++i)s[i]='0';}构造函数定义longlong(constchar*s1加法运算定义longlongoperator+(constlonglong&p1,constlonglong&p2){longlongt;inti,j=0;for(i=0;i<128;++i){t.s[i]=p1.s[i]-'0‘+p2.s[i]-'0‘+j;if(t.s[i]>10)j=t.s[i]/10;elsej=0; t.s[i]=t.s[i]%10+'0';}returnt;}加法运算定义longlongoperator+(const加法运算定义longlongoperator+(constlonglong&p1,constint&p2){longlongt;inti,j=0;for(i=0;i<128;++i){t.s[i]=p1.s[i]-'0‘+p2%10+j;p2=p2/10;if(t.s[i]>10)j=t.s[i]/10;elsej=0; t.s[i]=t.s[i]%10+'0';}returnt;}加法运算定义longlongoperator+(const显示函数定义voidshow(){inti=127;while(s[i]==‘0’)--i;//去掉高位0while(i>=0){cout<<s[i];--i;} cout<<endl;}显示函数定义voidshow()测试程序voidmain(){longlonga("123"),b("345"),c;c=a+b;c.show();c=a+5;c.show();}648128测试程序voidmain()648典型的运算符重载++和--的重载=的重载类型转换典型的运算符重载++和--的重载赋值运算符“=”的重载对任一类,如果用户没有自定义赋值运算符函数,那么系统为其生成一个缺省的赋值运算符函数,在对应成员间赋值。

X&X::operator=(constX&source){//成员间对应赋值}一旦创建了对象x1,x2,可以用x1=x2赋值。赋值运算符“=”的重载对任一类,如果用户没有自定义赋值运算符赋值运算符“=”的重载有时,使用缺省运算符函数会产生错误。如:#include<iostream.h>#include<string.h>Classstring{char*ptr;public:string(char*s){ptr=newchar[strlen(s)+1];strcpy(ptr,s);}~string(){deleteptr;}voidprint(){cout<<ptr<<endl;}};voidmain(){stringp1(“chen”);{stringp2(““);p2=p1;cout<<“p2:”;p2.print();}cout<<“p1:”;p1.print();}/*p1指向的空间会丢失*/赋值运算符“=”的重载有时,使用缺省运算符函数会产生错误。如解决方法显式定义一个赋值运算符重载函数,使p1和p2有各自的存储空间,实现方法如下:string&string::operator=(conststring&s){if(this==&s)return*this;deleteptr;ptr=newchar[strlen(s.ptr)+1];strcpy(ptr,s.ptr);return*this;}解决方法显式定义一个赋值运算符重载函数,使p1和p2有各自的#include<iostream.h>#include<string.h>classstring{char*ptr;public:string(char*s){ptr=newchar[strlen(s)+1];strcpy(ptr,s);} ~string(){deleteptr;} voidprint(){cout<<ptr<<endl;} string&operator=(conststring&);};string&string::operator=(conststring&s){if(this==&s)return*this;deleteptr;ptr=newchar[strlen(s.ptr)+1];strcpy(ptr,s.ptr);return*this;}voidmain(){stringp1("chen");{stringp2(""); p2=p1;cout<<"p2:";p2.print();}cout<<"p1:";p1.print();}#include<iostream.h>赋值运算符“=”重载的说明类的赋值运算符“=”只能重载为成员函数,而不能把它重载为友元函数。当重载为成员函数时,该函数只有一个参数。p1=p2相当于p1.operator=(p2)。如用友元函数,必须有两个参数operator=(p1,p2),如果p1为一常数,则会出错。类的赋值运算符“=”可以被重载,但重载的运算符函数operator=()不能被继承。赋值运算符“=”重载的说明类的赋值运算符“=”只能重载为成Longlong类型中重载赋值运算符Longlong&operator=(constchar*s1){inti=strlen(s1)-1,j=0; while(i>=0){if(s1[i]>'9'||s1[i]<'0') {cout<<"seterror";i=-1;} else{s[j]=s1[i];--i;++j;}} for(;j<128;++j)s[j]='0'; }在程序中可用:a=“1234567890123”;Longlong类型中重载赋值运算符Longlong&赋值运算符重载带来的问题在上面的赋值运算符重载函数中,函数的参数是char*,这样会使得c=a+b这样的运算不能执行,因为表达式的右边是一个对象而不是字符串。解决方法:可以用函数重载再写一个赋值函数,他的参数是对象赋值运算符重载带来的问题在上面的赋值运算符重载函数中,函数的典型的运算符重载++和--的重载=的重载类型转换典型的运算符重载++和--的重载类型转换--系统预定义类型间的转换隐式类型转换

※赋值时

※运算时显式类型转换※强制转换法:(类型名)表达式※函数法:类型名(表达式)类型转换--系统预定义类型间的转换隐式类型转换类型转换—类类型与系统预定义类型间的转换通过构造函数进行类型转换#include<iostream.h>classexample{intnum;public:example(intn){num=n;}voidprint(){cout<<num<<endl;}};voidmain(){examplex=6;//通过构造函数进行类型转换x.print();}类型转换—类类型与系统预定义类型间的转换通过构造函数进行类型类型转换—类类型与系统预定义类型间的转换通过类型转换函数进行类型转换声明格式:operator类型标识符()const;定义格式:类名::operator类型标识符()const{…;return类型标识符指定的变量;}说明:类类型转换函数:无函数返回类型,无参数。因为,总是转换成“类型标识符”所指出的类型,且被转换的总是本类的一个对象(由this指针指出)。类型转换函数只能定义为非静态的成员函数类型转换—类类型与系统预定义类型间的转换通过类型转换函数进行类型转换—类类型与系统预定义类型间的转换classCounter{intv1;charv2;public:Counter(intv=0,charvv='?'){v1=v;v2=vv;}

operatorchar(){returnv2;}

operatorint(){returnv1;}voiddisplay(){cout<<"Counter:v1="<<v1<<"v2="<<v2<<endl;}friendCounterfn(Counterc);};Counterfn(Counterc){c.v1=c.v1*2;returnc;}voidmain(){charx;inty;Counterc1(64,'%'),c2(99,'@');c1.display();c2.display();c2=fn(12345);//实参12345通过构造函数//Counter(intv=0,charvv='?')转换成Counter类型c2.display();x=c1;//通过成员函数转换成char型y=c1;//通过成员函数转换成int型cout<<x<<""<<y<<endl;}Counter:v1=64v2=%Counter:v1=99v2=@Counter:v1=24690v2=?%64

类型转换—类类型与系统预定义类型间的转换classCoun类型转换—类类型与系统预定义类型间的转换运算符重载与类型转换:在某些情况下,用户希望将类对象与基本数据类型进行运算,这可以通过运算符重载来完成。如要实现复数与整型数相加:类型转换—类类型与系统预定义类型间的转换运算符重载与类型转换类型转换—类类型与系统预定义类型间的转换运算符重载与类型转换:在某些情况下,用户希望将类对象与基本数据类型进行运算,这可以通过运算符重载来完成。如要实现复数与整型数相加:类型转换—类类型与系统预定义类型间的转换运算符重载与类型转换类型转换—类类型与系统预定义类型间的转换classcomplex{floatreal,imag;public:complex(floatr=0,floati=0){real=r;imag=i;}

friendcomplexoperator+(intx,complexy) {complextmp; tmp.real=x+y.real;tmp.imag=y.imag;returntmp;} voidprint(){cout<<real<<","<<imag<<endl;} };voidmain(){complexob1(10.5,20.5),ob2;intx=100;ob1.print();ob2=x+ob1;//整型变量与类对象相加ob2.print();}/*输出10.5,20.5110.5,20.5*/类型转换—类类型与系统预定义类型间的转换classcomp第11章运算符重载简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载简介输入输出流重载能否使类的对象也能像内置类型一样直接用cin和cout完成输入输出?方法是重载流插入<<和流提取>><<和>>的重载是使用友元函数输入输出流重载能否使类的对象也能像内置类型一样直接用cin和重载“<<”定义格式:ostream&operator<<(ostream&stream,constclass_name&obj){//操作代码returnstream;}重载“<<”定义格式:重载“<<”实例原有的实现方法#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}voidshow(){cout<<"x=“<<x<<"y=“<<y<<endl;}};voidmain(){Aa1(5,55);a1.show();}/*执行结果:x=5y=55*/重载“<<”实例原有的实现方法重载“<<”实例现在的实现方法classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}

friendostream&operator<<(ostream&op,constA&a);};ostream&operator<<(ostream&op,constA&a){op<<"x=“<<a.x<<"y=“<<a.y<<endl;returnop;}voidmain(){Aa1(5,55);cout<<a1;}/*执行结果:x=5y=55*/重载“<<”实例现在的实现方法Longlong类型的输出ostream&operator<<(ostream&ss,constlonglong&p){inti=127;while(p.s[i]=='0')--i;//去掉高位0while(i>=0){ss<<p.s[i];--i;} ss<<endl;returnss;}如定义了longlong类的对象a,在使用中可用cout<<a来输出Longlong类型的输出ostream&operator重载“>>”与重载输出操作符类似。其定义格式为:

istream&operator>>(istream&stream,class_name&obj){//操作代码returnstream;}重载“>>”与重载输出操作符类似。其定义格式为:第11章运算符重载简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载简介数组的缺陷数组无越界检查不能一次输入或输出整个数组不能比较两个数组数组作为参数传递时必须有一个额外的参数表示数组的大小数组不能直接赋值数组的缺陷数组无越界检查Array类设计一个整型数组的改进版保证数组不越界允许将一个数组赋给另一个数组数组对象自动知道数组的大小可以用==和!=直接比较两个数组Array类设计一个整型数组的改进版实现array类的关键--下标运算符“[]”的重载将某一函数的执行表示成数组中的下标形式。下标运算符重载时,只能显式声明一个参数,即下标值。其格式为

数组类型&operator[](inti)只能重载为成员函数实现array类的关键--下标运算符“[]”的重载将某一函classArray{

friendostream&operator<<(ostream&,constArray&);

friendistream&operator>>(istream&,Array&);

intsize;//sizeofthearray

int*ptr;//pointertofirstelementofarray

staticintarrayCount;

//#ofArraysinstantiatedpublic:

Array(int=10);

//defaultconstructor

Array(constArray&);

//copyconstructor

~Array();

//destructor

Array类的定义classArray{

friendostre

intgetSize()const;

//returnsize

constArray&operator=(constArray&);//assignarrays

booloperator==(constArray&)const;

//compareequal

//Determineiftwoarraysarenotequaland

//returntrue,otherwisereturnfalse(usesoperator==).

booloperator!=(constArray&right)const

{return!(*this==right);}

int&operator[](int);

//subscriptoperator

constint&operator[](int)const;

//subscriptoperator

staticintgetArrayCount()

//Returncountof

{return

arrayCount;}

//arraysinstantiated.

};

intgetSize()const;

Array类的实现—构造函数//InitializestaticdatamemberatfilescopeintArray::arrayCount=0;

//noobjectsyet//DefaultconstructorforclassArray(defaultsize10)Array::Array(intarraySize){

size=(arraySize>0?arraySize:10);

ptr=newint[size];//createspaceforarray

assert(ptr!=0);

//terminateifmemorynotallocated

++arrayCount;

//countonemoreobject

for(inti=0;i<size;i++)

ptr[i]=0;

//initializearray}Array类的实现—构造函数//Initializest拷贝构造函数//CopyconstructorforclassArray//mustreceiveareferencetopreventinfiniterecursion

Array::Array(constArray&init):size(init.size)

{

ptr=newint[size];//createspaceforarray

assert(ptr!=0);

//terminateifmemorynotallocated

++arrayCount;

//countonemoreobject

for(inti=0;i<size;i++)

ptr[i]

=init.ptr[i];

//copyinitintoobject

}拷贝构造函数//Copyconstructorfor1每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包括一个拷贝构造函数,其它的称为普通构造函数)。2对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数:对象复制可以将一个对象的所有数据成员的值赋给同类的另一个对象,如果对象的数据成员中不存在指针,则没有问题,但如果其中含有指针,则这种方式只是简单地把指针所指向的内容的地址复制过来,并没有复制其所指的内容。这可能并不是用户所期望的。这要通过自定义的复制策略来实现:拷贝构造函数和重载运算符“=”。1每个类只有一个析构函数和一个赋值函数,但可以有多个构造对象的复制在C++中,下面三种对象需要拷贝构造函数

1一个对象以值传递的方式传入函数体

2一个对象以值传递的方式从函数返回

3一个对象需要通过另外一个对象进行初始化拷贝构造函数的形式A(constA&)

对象的复制在C++中,下面三种对象需要拷贝构造函数

1拷贝构造函数和赋值函数拷贝构造函数是在对象创建时调用的,而赋值函数只能被已经存在了的对象调用。stringa("Hello");stringb("world");stringc=a//调用了拷贝构造函数,最好写成c(a)c=b//调用了赋值函数

拷贝构造函数和赋值函数拷贝构造函数是在对象创建时调用析构函数//DestructorforclassArray

Array::~Array()

{

delete[]ptr;

//reclaimspaceforarray

--arrayCount;

//onefewerobjects

}

//Getthesizeofthearray

intArray::getSize()const{returnsize;}析构函数//Destructorforclass=运算符重载//constreturnavoids:(al=a2)=a3

constArray&Array::operator=(constArray&right)

{

if(&right!=this){

if(size!=right.size){

delete[]ptr;

//reclaimspace

size=right.size;

//resizethisobject

ptr=newint[size];

assert(ptr!=0);

//terminateifnotallocated

}

for(inti=0;i<size;i++)ptr[i]=right.ptr[i];

}

return*this;

//enablesx=y=z;

}=运算符重载//constreturnavoids:判相等boolArray::oprator==(constArray&right)const

{

if(size!=right.size)

returnfalse;

//arraysofdifferentsizes

for(inti=0;i<size;i++)

if(ptr[i]

!=right.ptr[i])

returnfalse;//arraysarenotequal

returntrue;

//arraysareequal

}

判相等boolArray::oprator==(cons重载[]--检查下标是否越界int&Array::operator[](intsubscript)

{

assert(0<=subscript&&subscript<size);

returnptr[subscript];//referencereturn

}

constint&Array::operator[](intsubscript)const

{

assert(0<=subscript&&subscript<size);

returnptr[subscript];//constreferencereturn

}重载[]--检查下标是否越界int&Array::ope输入输出重载istream&operator>>(istream&input,Array&a)

{

for(inti=0;i<a.size;i++)

input>>a.ptr[i];

returninput;

//enablescin>>x>>y;

}

输入输出重载istream&operator>>(istostream&operator<<(ostream&output,constArray&a)

{

inti;

for(i=0;i<a.size;i++){

output<<setw(12)<<a.ptr[i];

if((i+1)%4==0)//4numbersperrowofoutput

output<<endl;

}

if(i%4!=0)

output<<endl;

returnoutput;

//enablescout<<~<<y;

}ostream&operator<<(ostream&Array类的使用intmain()

{

//noobjectsyet

cout<<"#ofarraysinstantiated="

<<Array::getArrayCount()<<'\n';

//createtwoarraysandprintArraycount

Arrayintegers1(7),integers2;

cout<<"#ofarraysinstantiated="

<<Array::getArrayCount()<<"\n\n";#ofarraysinstantiated=0

#ofarraysinstantiated

2Array类的使用intmain()

{

///printintegerslsizeandcontents

cout<<"Sizeofarrayintegers1is"

<<integers1.getSize()

<<"\nArrayafterinitialization:\n"

<<integersl<<'\n';

//printintegers2sizeandcontents

cout<<"Sizeofarrayintegers2is"

<<

integers2.getSize()

<<"\nArrayafterinitialization:\n"

<<integers2<<'\n';Sizeofarrayintegerslis7

Arrayafterinitialization:

0

0

0

0

0

0

0

0

Sizeofarrayintegers2is10

Arrayafterinitialization:

0

0

0

0

0

0

0

0

0

0//printintegerslsizeandco//inputandprintintegerslandintegers2

cout<<"Input17integers:\n";

cin>>integers1>>integers2;

cout<<"Afterinput,thearrayscontain:\n"

<<"integersl:\n"<<infegers1

<<"integers2:\n"<<integers2<<'\n';

//useoverloadedinequality(!=)operator

cout<<"Evaluating:integers1!=integers2\n";

if(integers1!=integers2)

cout<<"Theyarenotequal\n";

Input17integers:

1234567891011121314151617

Afterinput,thearrayscontain:

integersl:

1

2

3

4

5

6

7

integers2:

8

9

10

11

12

13

14

15

16

17

Evaluating:integers1!=integers2

Theyarenotequal//inputandprintintegersla//createarrayintegers3usingintegers1asan

//initlizer;printsizeandcontents

Arrayintegers3(integers1);

cout<<"\nSizeofarrayintegers3is"

<<integers3.getSize()

<<"\nArrayafterinitialization:\n"

<<integers3<<'\n';Sizeofarrayintegers3is7

Arrayafterinitialization:

1

2

3

4

5

6

7//createarrayintegers3usin//useoverloadedassignment(=)operator

cout<<"Assigningintegers2tointegers1:\n";

integers1=integers2;

cout<<"integersl:\n"<<integers1

<<"integers2:\n"<<integers2<<'\n';

//useoverloadedequality(==)operator

cout<<"Evaluating:integers1==integers2\n";

if(integers1==integers2)

cout<<"Theyareequal\n\n";Assigningintegers2tointeqersl:

integersl:

8

9

10

11

12

13

14

15

16

17

integers2:

8

9

10

11

12

13

14

15

16

17

Evaluating:integersl==integers2

Theyareequal//useoverloadedassignment(//useoverloadedsubscriptoperator//tocreatervalue

cout<<"integers1[5]is"<<integers1[5]<<'\n';

//useoverloadedsubscriptoperator//tocreatelvalue

cout<<"Assigning1000tointegers1[5]\n";

<<

integers1[5]=1000;

cout<<"integers1:\n"<<integers1<<'\n';integersl[5]is=13

Assigning1000tointegersl[5]

integersl:

8

9

10

11

12

1000

14

15

16

17//useoverloadedsubscriptop//attempttouseoutofrangesubscript

cout<<“Attempttoassign1000tointegersl[15]”<<endl;

integers1[15]=1000;

//ERROR:outofrange

return0;

}Attempttoassign1000tointegersl[15]

Assertionfailed:0<=subscript&&subscript<size,

fileArrayl.cpp,line87

abnormalprogramtermination//attempttouseoutofrange第11章运算符重载简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载简介实例研究:string类在C语言中,string不是内置类型,不能用系统预制的运算符来进行操作。所有的操作都是通过字符串函数来实现目的:创建一种字符串类型,使之可以用预制的运算符来操作字符串。手段:通过运算符重载具体内容见教材P459实例研究:string类在C语言中,string不是内置类型类String的拷贝构造函数与赋值函数

//拷贝构造函数

String::String(constString&other)

{

//允许操作other的私有成员m_data

intlength=strlen(other.m_data);

m_data=newchar[length+1];

strcpy(m_data,other.m_data);

}

//赋值函数

String&String::operate=(constString&other)

{

//(1)检查自赋值

if(this==&other)

return*this;

//(2)释放原有的内存资源

delete[]m_data;

//(3)分配新的内存资源,并复制内容

intlength=strlen(other.m_data);

m_data=newchar[length+1];

strcpy(m_data,other.m_data);

//(4)返回本对象的引用

return*this;

}

类String的拷贝构造函数与赋值函数

//拷贝构造函小结运算符重载的注意事项如果左边的操作数必须是一个不同的类的对象,该运算符必须作为一个非成员函数来实现转换构造函数是带有一个参数的构造函数小结运算符重载的注意事项第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介运算符重载使得系统的内置运算符适用于类的对象之间的操作。提高程序的可读性。运算符重载使得系统的内置运算符适用于类的对象之间的操作。提高问题的提出希望某些运算符能够对整个对象进行操作,而不是C中的简单操作.例如:+运算符能够实现2个对象间的加。类A的对象a1、a2、a3,希望:a3=a1+a2;

即:分别把对象a1和a2的各个数据成员值对应相加,然后赋给对象a3。问题的提出希望某些运算符能够对整个对象进行操作,而不是C中的问题的提出把某些事交给系统去做,用户只要知道相加就可提出运算符重载,扩充运算符的功能。即:对运算符进行重载定义,然后使用,由系统自动判断究竟采用哪一个具体的运算符。增强了C++语言的可扩充性。问题的提出把某些事交给系统去做,用户只要知道相加就可运算符重载的限制不是所有的运算符都能重载重载不能改变运算符的优先级和结合性重载不能改变运算符的操作数个数不能创建新的运算符不能改变用于内部类型对象时的含义用于用户自定义类型对象,或者和内部类型的对象混合使用运算符重载的限制不是所有的运算符都能重载可以重载的运算符+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

==

!=

<=

>=

&&

||

++

--

->*

->

[]

()

new

delete

new[]

delete[]

.

.*

::

?:

sizeof

不能重载的运算符:可以重载的运算符+

-

运算符重载的实现方法

用普通函数实现用成员函数实现用友元函数实现运算符重载的实现方法用普通函数实现第11章运算符重载:字符串和数组对象简介用普通函数重载用友员函数重载用成员函数重载典型的运算符重载输入输出重载实例研究:array类实例研究:string类第11章运算符重载:字符串和数组对象简介用普通函数实现运算符重载创建运算符函数运算符函数名为:

operator后接一个要重载的运算符。如:要重载“+”运算,函数名为operator+。重载“-”运算,函数名为operator-。参数表为要参加运算的对象,返回值为运算结果用普通函数实现运算符重载创建运算符函数运算符重载函数实例#include<iostream.h>classcomplex{publ

温馨提示

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

最新文档

评论

0/150

提交评论