运算符重载和类型转换精.ppt
运算符重载和类型转换运算符重载和类型转换第1页,本讲稿共34页主要内容主要内容n n运算符重载的目的运算符重载的目的n n运算符重载概述运算符重载概述n n重载的规则和限制n n如何重载运算符如何重载运算符n n常见运算符的重载常见运算符的重载n n类型转换类型转换n n小结小结第2页,本讲稿共34页class Complexclass Complex public:public:Complex(float r=0,float i=0)real=r;image=i;Complex(float r=0,float i=0)real=r;image=i;Complex add(const Compex&c)Complex add(const Compex&c)return Complex(real+c.real,image+c.image);return Complex(real+c.real,image+c.image);private:private:float real,image;float real,image;void main()void main()int i=29,j=870,k;int i=29,j=870,k;float x=2.6,y=2.4;float x=2.6,y=2.4;k=i+j;k=i+j;float z=x+y;float z=x+y;Complex c1(3.2,4.6),c2(6.2,8.7),c3;Complex c1(3.2,4.6),c2(6.2,8.7),c3;c3=c1.add(c2);c3=c1.add(c2);第3页,本讲稿共34页运算符重载概述运算符重载概述n n运算符运算符运算符运算符是一些系统预定义的函数名称,即用一些特定的符号是一些系统预定义的函数名称,即用一些特定的符号表示各种运算。每个运算符对运算数据都有一定要求。表示各种运算。每个运算符对运算数据都有一定要求。n n C+C+中预定义的运算符的操作对象中预定义的运算符的操作对象只能是基本数据类型只能是基本数据类型只能是基本数据类型只能是基本数据类型,实,实际上,对于很多用户自定义类型,也需要有类似的运算操作,际上,对于很多用户自定义类型,也需要有类似的运算操作,这就提出了对运算符进行重新定义,赋予已有符号以新功能这就提出了对运算符进行重新定义,赋予已有符号以新功能的要求。的要求。n n运算符重载运算符重载运算符重载运算符重载是对已有的运算符赋予多重含义,同一个运算符是对已有的运算符赋予多重含义,同一个运算符作用于不同类型的数据导致不同类型的行为。作用于不同类型的数据导致不同类型的行为。n n运算符重载的运算符重载的实质就是函数重载实质就是函数重载实质就是函数重载实质就是函数重载。在实现过程中,首先把指。在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用为运算符函数的实参,然后根据实参的类型来确定需要调用的函数,这个过程是在编译过程中完成的。的函数,这个过程是在编译过程中完成的。第4页,本讲稿共34页运算符重载的规则和限制运算符重载的规则和限制n n不可以重载的运算符有:不可以重载的运算符有:.*:?:sizeof.*:?:sizeofn n只能重载只能重载C+C+语言中已有的运算符,不可臆造新的。语言中已有的运算符,不可臆造新的。n n运算符重载后优先级和结合性都不会改变,运算符重载后优先级和结合性都不会改变,n n不能改变操作数个数不能改变操作数个数,单目只能重载为单目运算符,双目只能重载为双目运算符单目只能重载为单目运算符,双目只能重载为双目运算符n n不能改变运算符对预定义类型数据的操作方式,即重载运算符时,其操作数中至少应该有一个不能改变运算符对预定义类型数据的操作方式,即重载运算符时,其操作数中至少应该有一个是自定义类型。是自定义类型。n n重载的运算符应保持其原有的基本语义。重载的运算符应保持其原有的基本语义。n nC+C+规定:规定:=-()=-()只能重载为成员函数形式:只能重载为成员函数形式:n n 作为提取和插入运算符使用时,只能用友元函数重载作为提取和插入运算符使用时,只能用友元函数重载第5页,本讲稿共34页运算符函数运算符函数n n定义运算符重载函数的一般格式:定义运算符重载函数的一般格式:operator operator ()././函数体函数体 n ntypetype为函数返回值的类型;为函数返回值的类型;为要重载的运算符;为要重载的运算符;argarg为函数的形参表,为函数的形参表,operatoroperator是关键是关键字,它与其后的运算符一起构成函数名。字,它与其后的运算符一起构成函数名。n n为了提高访问效率,运算符重载函数通常需要直接访问对象的私有或保护的数据成员,因此为了提高访问效率,运算符重载函数通常需要直接访问对象的私有或保护的数据成员,因此运算符重载函数通常为运算符重载函数通常为类的成员函数类的成员函数或者或者友元函数友元函数。第6页,本讲稿共34页重载为类的成员函数重载为类的成员函数重载为类的成员函数重载为类的成员函数n n双目运算符双目运算符双目运算符双目运算符 B B 如果要重载如果要重载 B B 为类的成员函数,使之能够实现表达式为类的成员函数,使之能够实现表达式 oprd1 oprd1 B oprd2B oprd2,其中,其中 oprd1oprd1 为为A A 类对象,则类对象,则 B B 应被重载为应被重载为 A A 类的类的成员函数,形参类型应该是成员函数,形参类型应该是 oprd2oprd2 所属的类型。所属的类型。经重载后,经重载后,oprd1 B oprd2oprd1 B oprd2 相当于相当于 oprd1.operator B(oprd2)oprd1.operator B(oprd2)n n前置单目运算符前置单目运算符前置单目运算符前置单目运算符 UU 如果要重载如果要重载 U U 为类成员函数,使之能够实现表达式为类成员函数,使之能够实现表达式 U oprdU oprd,其中,其中 oprdoprd 为为A A类对象,则类对象,则 U U 应被重载为应被重载为 A A 类的成员函数,类的成员函数,无形参。经重载后,表达式无形参。经重载后,表达式 U oprdU oprd 相当于相当于 oprd.operator Uoprd.operator U()()第7页,本讲稿共34页n n后置运算符后置运算符后置运算符后置运算符“+”+”和和和和“”如果要实现表达式如果要实现表达式如果要实现表达式如果要实现表达式oprd+oprd+或或或或oprd oprd ,其中,其中,其中,其中oprdoprd为为为为A A 类类类类对象,那么运算符重载函数中要带一个整型对象,那么运算符重载函数中要带一个整型对象,那么运算符重载函数中要带一个整型对象,那么运算符重载函数中要带一个整型(int)(int)形参。形参。形参。形参。经经经经重载后,重载后,重载后,重载后,oprd+oprd+相当于相当于相当于相当于 oprd.operator+(0)oprd.operator+(0)oprd oprd 相当于相当于相当于相当于 oprd.operator oprd.operator (0)(0)n n前增量与后增量的区别前增量与后增量的区别前增量与后增量的区别前增量与后增量的区别 使用前增量时,对对象(操作数)进行增量修改,然后使用前增量时,对对象(操作数)进行增量修改,然后使用前增量时,对对象(操作数)进行增量修改,然后使用前增量时,对对象(操作数)进行增量修改,然后再返回该对象,参数与返回的是同一个对象再返回该对象,参数与返回的是同一个对象再返回该对象,参数与返回的是同一个对象再返回该对象,参数与返回的是同一个对象 使用后增量时,必须在增量之前返回原有的对象。后增量使用后增量时,必须在增量之前返回原有的对象。后增量使用后增量时,必须在增量之前返回原有的对象。后增量使用后增量时,必须在增量之前返回原有的对象。后增量操作返回的是原有对象值,不是原有对象,原有对象已经操作返回的是原有对象值,不是原有对象,原有对象已经操作返回的是原有对象值,不是原有对象,原有对象已经操作返回的是原有对象值,不是原有对象,原有对象已经被增量修改。被增量修改。被增量修改。被增量修改。第8页,本讲稿共34页重载为类的友元函数重载为类的友元函数重载为类的友元函数重载为类的友元函数n n此时运算所需的操作数都是通过函数的参数表来传递,在参数表中形参从左此时运算所需的操作数都是通过函数的参数表来传递,在参数表中形参从左到右的顺序就是运算符操作数的顺序。到右的顺序就是运算符操作数的顺序。n n双目运算符双目运算符 B B重载后,重载后,(ch18_2ch18_2)表达式表达式oprd1 B oprd2oprd1 B oprd2 等同于等同于operator B(oprd1,oprd2)operator B(oprd1,oprd2)n n前置单目运算符前置单目运算符 B B重载后,重载后,B oprd B oprd 等同于等同于 operator B(oprd)operator B(oprd)n n后置单目运算符后置单目运算符 +和和-重载后,此时函数的形参有两个,一个是类的对象,重载后,此时函数的形参有两个,一个是类的对象,另一个是整型另一个是整型(int)(int)形参形参 oprd B oprd B 等同于等同于 operator B(oprd,0)operator B(oprd,0)第9页,本讲稿共34页两种重载形式的比较两种重载形式的比较n n对双目运算符而言,成员运算符函数带有一个参数,而友元运算符函对双目运算符而言,成员运算符函数带有一个参数,而友元运算符函数带有两个参数;对单目运算符而言,成员运算符函数不带参数,而数带有两个参数;对单目运算符而言,成员运算符函数不带参数,而友元运算符函数带有一个参数友元运算符函数带有一个参数 。n n双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但有一种情况必须使用友元函数,如加法运算。有一种情况必须使用友元函数,如加法运算。n n运算符函数调用形式运算符函数调用形式习惯形式习惯形式习惯形式习惯形式友元调用形式友元调用形式友元调用形式友元调用形式成员调用形式成员调用形式成员调用形式成员调用形式a+ba+boperator+(a,b)operator+(a,b)a.operator+(b)a.operator+(b)-a-aoperator-(a)operator-(a)a.operator-()a.operator-()a+a+operator+(a,0)operator+(a,0)a.operator+(0)a.operator+(0)第10页,本讲稿共34页成员与友元运算符函数选取经验成员与友元运算符函数选取经验成员与友元运算符函数选取经验成员与友元运算符函数选取经验n n对于对于单目运算符,建议选择成员函数单目运算符,建议选择成员函数。n n对于运算符对于运算符“=()()-”-”只能作为成员函数只能作为成员函数。n n对于运算符对于运算符“+=-=/=*=&=!=%=-。确保指向类对象的指针总是指向某个有意义的对象(有效内存地址),即创建一个确保指向类对象的指针总是指向某个有意义的对象(有效内存地址),即创建一个指向对象的指向对象的“智能指针智能指针”(smart pointersmart pointer),否则就返回错误信息。这样避免了),否则就返回错误信息。这样避免了对空指针或垃圾指针对空指针或垃圾指针(garbage pointer)(garbage pointer)内容的存取。由于右操作数是对象的成员,内容的存取。由于右操作数是对象的成员,该成员类型不能确定,所以该成员类型不能确定,所以 -只能作为一元运算符重载。只能作为一元运算符重载。n n重载下标运算符重载下标运算符 ,可增加数组检索的安全性,可增加数组检索的安全性。n n重载函数调用运算符(),是唯一可带多个右操作数的运算符函数。重载函数调用运算符(),是唯一可带多个右操作数的运算符函数。第12页,本讲稿共34页重载重载=运算符解决指针悬挂运算符解决指针悬挂n nn nClass stringClass stringn nPublic:Public:n nString(char*s)String(char*s)n nPtr=new charstrlen(s)+1;Strcpy(ptr,s);Ptr=new charstrlen(s)+1;Strcpy(ptr,s);n nstring()Delete ptr;string()Delete ptr;n nVoid print()coutptrendl;Void print()coutptrendl;n nString&operator=(const string&);String&operator=(const string&);n nPrivate:Private:n nChar*ptr;Char*ptr;n n;n nString&string:operator=(const string&s)String&string:operator=(const string&s)n n If(this=&s)return*this;If(this=&s)return*this;n n Delete ptr;Delete ptr;n n Ptr=new charstrlen(s.ptr)+1;Ptr=new charstrlen(s.ptr)+1;n n strcpy(ptr,s.ptr);strcpy(ptr,s.ptr);n n Return*this;Return*this;n n Void main()String p1(“book”);String p2(“pen”);P1=p2;Cout“p2:”;P1.print();第13页,本讲稿共34页重载重载重载重载new new 和和和和deletedeleten nn nClass RectClass Rectn n n nPublic:Public:n nRect(int l,int w)Length=1;width=w;Rect(int l,int w)Length=1;width=w;n nVoid disp(0Void disp(0n n Cout“length*widthendl;Cout“length*widthendl;n nVoid*Rect:operator new(size_t size)Void*Rect:operator new(size_t size)n n n nCout“reload new“endl;Cout“reload new“endl;n nRetrun molloc(size);Retrun molloc(size);n n n nVoid Rect:operator delete(void*p)Void Rect:operator delete(void*p)n n n nCout“reload delete free”endl;Cout“reload delete free”disp();Delete p;第14页,本讲稿共34页重载重载n n ostream&operator(ostream&ostream&operator(ostream&out,class_name&obj)out,class_name&obj)n n n noutobj.item1;outobj.item1;n n;n nOutobj.item2;Out(istream&in,class_name&Istream&operator(istream&in,class_name&obj)obj)n n n nInobj.item1;Inobj.item1;n nInobj.item2;Inobj.item2;n nn nReturn in;Return in;第15页,本讲稿共34页n nClass coordClass coordInt x,y;Int x,y;Public:Public:Coord(int i=0,int j=0)Coord(int i=0,int j=0)X=I;y=j;X=I;y=j;Friend ostream&operator(ostream&stream,coord&ob)Friend ostream&operator(ostream&stream,coord&ob)Stream0b.x“,”ob.yendl;Stream0b.x“,”ob.yendl;Return stream;Return stream;Main()Main()Coord a(55,66),b(100,200);Coord a(55,66),b(100,200);Coutab;Coutab;Return 0;Return 0;第16页,本讲稿共34页n nn nClass three_dClass three_dn nPublic:Public:n nTrhrr_d(int a,int b,int c)Trhrr_d(int a,int b,int c)n nX=a;y=b;z=c;X=a;y=b;z=c;n nFriend ostream&operator(ostreams&ouput,three_d&ob);Friend ostream&operator(istream&itput,three_d&ob);Friend istream&operator(istream&itput,three_d&ob);n nPrivate:Private:n nInt x,y,z;Int x,y,z;n n;n nOstream&operator(ostream&output,three_d&ob)Ostream&operator(ostream&output,three_d&ob)n n n nOutputob.x“,”;Outputob.x“,”;n nOutputob.y“,”;Outputob.y“,”;n nOutputob.zendl;Outputob.z(istream&input,three_d&ob)Istream&operator(istream&input,three_d&ob)n n n nCout“Enter x,y,z value:”;Coutob.x;Inputob.x;n nInputob.y;Inputob.y;n nInputob.z;Inputob.z;n nReturn input;Return input;n n n nMain()Main()n n n nThree_d obj(10,20,30);Three_d obj(10,20,30);n nCoutobj;Coutobj;Cinobj;n nCoutobj;Coutobj;n nReturn 0;Return 0;n n 第18页,本讲稿共34页重载关系运算符:重载关系运算符:重载关系运算符:重载关系运算符:,=n n举例举例TimeTime类的类的 自增自增,时间上加若干秒,时间的比较。时间上加若干秒,时间的比较。第19页,本讲稿共34页类型转换类型转换类型转换类型转换n n系统预定义类型间的转换系统预定义类型间的转换 隐式类型转换(隐式类型转换(隐式类型转换(隐式类型转换(编译器根据需要自动对数据类型作转换编译器根据需要自动对数据类型作转换)显式类型转换显式类型转换显式类型转换显式类型转换(强制转换、函数法)(强制转换、函数法)n n类类型与系统预定义类型间的转换类类型与系统预定义类型间的转换 通过带构造函数进行类型转换:通过带构造函数进行类型转换:通过带构造函数进行类型转换:通过带构造函数进行类型转换:只能实现从基本类型向自定义只能实现从基本类型向自定义类类型的转换,参数的类型即要转换的类型类类型的转换,参数的类型即要转换的类型 通过类类型转换函数进行类型转换通过类类型转换函数进行类型转换通过类类型转换函数进行类型转换通过类类型转换函数进行类型转换 operator operator 类型名():类型名():类型名():类型名():可以把源类类型转换成另一种目的类型,可以把源类类型转换成另一种目的类型,不用参数不用参数n n从某个类到另外一个类的转换:使用转换函数,要使用参数从某个类到另外一个类的转换:使用转换函数,要使用参数第20页,本讲稿共34页转换函数转换函数转换函数转换函数n n对一个类建立健立隐式转换规则需要构造一个转换函数,对一个类建立健立隐式转换规则需要构造一个转换函数,该函数作为类的成员,在以把该类的对象和其他数据类型该函数作为类的成员,在以把该类的对象和其他数据类型的对象进行相互转换的对象进行相互转换。声明了转换函数,就告诉了编译器,。声明了转换函数,就告诉了编译器,当根据句法判定需要类型转换时,就调用该函数。当根据句法判定需要类型转换时,就调用该函数。n n有两种转换函数:一有两种转换函数:一种是转换构造函数种是转换构造函数,另一种是成员转另一种是成员转换函数。换函数。需要采用哪种转换需要采用哪种转换 灵敏取决于转换的方向。灵敏取决于转换的方向。n n转换构造函数转换构造函数:当一个构造函数公有一个参数,且该参数:当一个构造函数公有一个参数,且该参数是不同于该类的一个数据类型时,这样的构造函数就叫转是不同于该类的一个数据类型时,这样的构造函数就叫转换构造函数。转换构造函数把别的数据类型的对象转换为换构造函数。转换构造函数把别的数据类型的对象转换为该类的一个对象。和其他构造函数一样,如果声明该类的一个对象。和其他构造函数一样,如果声明 类对象类对象 的初始化表同转换构造函数的参数表相匹配,该函数就会的初始化表同转换构造函数的参数表相匹配,该函数就会被调用。当在需要该类的地方使用了别的数据类型,编译被调用。当在需要该类的地方使用了别的数据类型,编译器就会调用转换构造函数进行转换。器就会调用转换构造函数进行转换。n n成员转换函数成员转换函数:成员转换函数把该类的对象转换为其他数:成员转换函数把该类的对象转换为其他数据类型的对象据类型的对象 ,声明中要加,声明中要加operator:operator:n noperator long();Classname:operator long()operator long();Classname:operator long()第21页,本讲稿共34页转换构造函数举例转换构造函数举例转换构造函数举例转换构造函数举例1 1n n#include#includen n#include#includen nusing namespace std;using namespace std;n n#include#includen nclass Dateclass Daten n int year,month,day;int year,month,day;n npublic:public:n nDate(time_t);/Date(time_t);/转换构造函数转换构造函数n nvoid display();void display();n n;n n/显示日期的成员函数显示日期的成员函数n nvoid Date:display()void Date:display()n n char yr5;char yr5;n nif(year10)if(year10)n nsprintf(yr,0%d,year);sprintf(yr,0%d,year);n nelseelsen nsprintf(yr,%d,year);sprintf(yr,%d,year);n ncoutyr-month-coutyr-month-dayendl;daytm_mday;month=tim-tm_mon+1;year=tim-tm_year;if(year=100)year-=100;/*/*main()函数函数/*int main()time_t now=time(0);Date dt(now);dt.display();return 0;第22页,本讲稿共34页转换构造函数举例转换构造函数举例转换构造函数举例转换构造函数举例2 2n nclass CustomDateclass CustomDaten n n npublic:public:n n int da,yr;int da,yr;n n CustomDate(int d=0,int CustomDate(int d=0,int y=0)da=d;yr=y;y=0)da=d;yr=y;n n void display()void display()n n coutendlyr-da;coutendlyr-da;n n;class Date int month,day,year;public:Date(int m=0,int d=0,int y=0)month=m;day=d;year=y;/构造函函数转换函数构造函函数转换函数 Date(const CustomDate&);/成员转换函数成员转换函数 operator CustomDate();void display()coutendlyear-month-day;static int dys=0,31,28,31,30,31,30,31,31,30,31,30,31;第23页,本讲稿共34页n n/构造函数转换函数(构造函数转换函数(构造函数转换函数(构造函数转换函数(Date-CustomDate)Date-CustomDate)n nDate:Date(const CustomDate&jd)Date:Date(const CustomDate&jd)n n n n year=jd.yr;year=jd.yr;n n day=jd.da;day=jd.da;n n for(month=0;month11;month+)for(month=0;monthdysmonth)if(daydysmonth)n nday=day-dysmonth;day=day-dysmonth;n n else elsen nbreak;break;n n month+;month+;n n/成员转换函数成员转换函数(CustomDate-Date)Date:operator CustomDate()CustomDate cd(day,year);for(int i=0;imonth-1;i+)cd.da=cd.da+dysi;return cd;int main()Date dt(11,17,2011);CustomDate cd;cd=dt;/将将Date转换转换CustomDate dt.display();cd.display();Date dt2;dt2=cd;dt2.display();return 0;第24页,本讲稿共34页成员转换函数举例成员转换函数举例成员转换函数举例成员转换函数举例n n#include#includen n#include#includen nusing namespace std;using namespace std;n n/Date/Date类声明类声明n nclass Dateclass Daten n n nint year,month,day;int year,month,day;n npublic:public:n n Date(int y,int m,int d)Date(int y,int m,int d)n n year=y;month=m;day=d;year=y;month=m;day=d;n n/成员转换函数成员转换函数n noperator long();operator long();n n void display()void display()n n n n coutendlyear-month-day;coutendlyear-month-day;n n n n;/成员转换函数成员转换函数Date:operator long()Date:operator long()static int dys=0,31,28,31,30,static int dys=0,31,28,31,30,31,30,31,31,30,31,30,31;31,30,31,31,30,31,30,31;long days=year-1900;long days=year-1900;days=days*365;days=days*365;days=days+year/4;days=days+year/4;for(int i=1;imonth-1;i+)for(int i=1;imonth-1;i+)days=days+dysi;days=days+dysi;days=days+day;days=days+day;return days;return days;int main()int main()Date xmas(1997,12,25);Date xmas(1997,12,25);long since=xmas;long since=xmas;coutsince daysendl;coutsince daysendl;return 0;return 0;第25页,本讲稿共34页调用转换构造的情形调用转换构造的情形调用转换构造的情形调用转换构造的情形n n参数传递参数传递n n初始化初始化n n返回值返回值n n表达式语句表达式语句第26页,本讲稿共34页通过构造函数进行类型转换通过构造函数进行类型转换n nn nClass exampleClass examplen nPublic:Public:n nExample(int);Example(int);n nVoid print();Void print();n nPrivate:Private:n nInt num;Int num;n n;n nExample:example(int n)Example:example(int n)n n n nNum=n;Num=n;n nCout“Intializeing Cout“Intializeing with:”numendl;with:”numendl;n n n nVoid example:print()Void example:print()n n n nCout“num=“numendl;Cout“num=“numendl;n n Void main()Example x=example(3);X.print();Example y=6;y.print();Y=8;y.print();第27页,本讲稿共34页通过类类型转换函数进行类型转换通过类类型转换函数进行类型转换n nn nClass complexClass complexn n.n nOperator float()Operator float()n n n nReturn real;Return real;n n n nOperator int()Operator int()n n n nReturn int(real);Return int(real);n nVoid print()Void print()n n n nCout(real,imag)Cout(real,imag)endl;endl;n n n nPrivate:Private:n nFloat real,imag;Float real,imag;n n;n nVoid main()Void main()n n n nComplex a(2.2,4.4);Complex a(2.2,4.4);n nA.print();A.print();n nCoutflaot9a)*0.5endl;Coutflaot9a)*0.5endl;n nComplex b(4,6);Complex b(4,6);n nB.print();B.print();n nCoutint(b)*2endl;Coutint(b)*2endl;n n 第28页,本讲稿共34页通过类类型转换函数进行隐式转换通过类类型转换函数进行隐式转换通过类类型转换函数进行隐式转换通过类类型转换函数进行隐式转换n nn nClass complexClass complexn n.n nComplex(int i=0)Complex(int i=0)n nreal=imag=i/2;real=imag=i/2;n n n nOperator int()Operator int()n n n nReturn int(real);Return int(real);n nVoid print()Void print()n n n nCout(real,imag)Cout(real,imag)endl;endl;n n n nPrivate:Private:n nFloat real,imag;Float real,imag;n n;n nVoid main()Void main()n n n nComplex a1(1,2),a2(3,4);a1.print();Complex a1(1,2),a2(3,4);a1.print();n nA2.print();A2.print();n nComplex a3;Complex a3;n nA3=a1+a2;A3=a1+a2;n nA3.print();A3.print();n n 第29页,本讲稿共34页小结小结小结小结n n使用运算符重载可以使程序易于理解并易于对对象进行操使用运算符重载可以使程序易于理解并易于对对象进行操作。但应注意不要改变优先级和结合性,不能改变运算符作。但应注意不要改变优先级和结合性,不能改变运算符操作数的数量,也不能发明新运算符。操作数的数量,也不能发明新运算符。n n如果在类中没有说明本身的拷贝构造函数和赋值运算符,如果在类中没有说明本身的拷贝构造函数和赋值运算符,编译程序将会提供,但它们都只是对对象进行成员浅拷贝。编译程序将会提供,但它们都只是对对象进行成员浅拷贝。n n在前增量和后增量运算符定义中,使用在前增量和后增量运算符定义中,使用intint形参只是为了标形参只是为了标志前后有别,没有其它作用。志前后有别,没有其它作用。n n拷贝构造函数用已存在的对象创建一个相同的新对象。而拷贝构造函数用已存在的对象创建一个相同的新对象。而赋值运算符把一个对象的成员变量值赋予一个已存在的同赋值运算符把一个对象的成员变量值赋予一个已存在的同类对象的同名变量。类对象的同名变量。n nthisthis指针指向当前的对象,它是所有成员函数的不可见的指针指向当前的对象,它是所有成员函数的不可见的参数,在重载运算符时,经常返回参数,在重载运算符时,经常返回thisthis指针的间接引用。指针的间接引用。第30页,本讲稿共34页n n1.1.编写商店卖商品的程序,商品类有商品名,商品编写商店卖商品的程序,商品类有商品名,商品IDID,price,number,totalprice,number,total。并对所售商品进行统计。并对所售商品进行统计。n n2.2.自定义文档类与视图类,并定义自定义文档类与视图类,并定义mainmain函数进行测试。函数进行测试。n n3.3.自定义学生类,作业类,教师类,编写学生教作业,教自定义学生类,作业类,教师类,编写学生教作业,教师批阅作业的程序。师批阅作业的程序。n n4.4.自定义邮件类,用于自动生成电子邮件信息。自定义邮件类,用