版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
3.3静态类成员3.3.1静态数据成员
希望数据为类的所有对象共享,而不是每个类对象维持一个独立的数据成员。例如:计数在程序的任意一点一共创建了多少个此类类型的对象。静态数据成员对每个类类型只有一个拷贝,由该类对象共享访问。非静态数据成员对每个类对象都有自己的拷贝。可以实现信息隐藏,可以是private成员。3.3.1.1类定义内声明在类体中数据成员声明前加上static关键字,使该数据成员成为静态的例如:classstudent{intnum;floatscore;public:staticfloatpassmark;staticintpassnum;3.3静态类成员1student(inta,floatf){num=a;score=f;}};3.3.1.2类定义外初始化
¤语法:数据类型类名::数据成员名=初值;注意:①如果没有初值,系统自动初始化为0。②整型const静态数据成员可以在类定义体内用常量值初始化,但仍要在类定义体外定义该数据成员且不能再指定初始值。③静态数据成员的初始化不应该放在头文件中。一般放在类定义之后,main函数之前。产生类对象之前可能用到静态数据成员。例如:classAccout{{staticconstintnamesize=16;staticconstcharname[namesize];};constintAccout::namesize;constcharAccout::name[namesize]=”savingaccount”;3.3.1.3静态数据成员的访问student(inta,flo2类的成员函数中访问:用静态数据成员名直接访问非成员函数中访问public静态数据成员:类名::静态数据成员名对象.静态数据成员名指向对象的指针->静态数据成员名例如:计数已创建对象的数目classData{intnum;floatscore;public:staticintobject;Data(inta,floatf):num(a),score(f){object++;}~Data(){object--;}};类的成员函数中访问:用静态数据成员名直接访问33.3.2静态成员函数
希望在产生对象之前访问private静态数据成员3.3.2.1声明与定义在类内普通成员函数声明前加上static关键字,在类外定义前不需再加static。注意:静态成员函数没有this指针,不能访问类的非静态成员,只能访问类的静态数据成员或是调用其它静态成员函数。3.3.2.2调用类名::静态函数名(参数表);对象.静态函数名(参数表);指向对象的指针->静态函数名(参数表);例如:classSmall{staticintobject;public:Small(){object++;}staticintget_n(){returnobject;}3.3.2静态成员函数4~Small(){object--;}};intSmall::object=0;intmain(){intn;n=Small::get_n();//…}3.3.3全局、静态局部类对象
3.3.3.1局部静态类对象在函数或复合语句内,用static关键字定义的对象。例如:intfun(){staticData(1,89.0);return0;}代码执行过程中第一次遇到该对象定义时,构造函数被调用,程序运行中仅调用一次;在程序运行结束前,调用析构函数,也只调用一次。例如:~Small(){o5classdemo{public:demo(){cout<<”objectconstructor\n”;}~demo(){cout<<”objectdestructor\n”}};voidfun(){staticdemod1;}intmain(){cout<<"mainstart\n";fun();cout<<"again\n";fun();输出:mainstartcout<<"mainend\n";}objectconstructoragainmainendobjectdestructorclassdemo{63.3.3.2全局类对象在函数外定义的对象。构造函数在main函数执行前被调用,析构函数在程序运行结束前调用。例如:classdemo{public: demo(){cout<<"objectconstructor\n";} ~demo(){cout<<"objectdestructor\n";}};intmain(){ cout<<"mainstart\n";cout<<"mainend\n";return0;}输出:objectconstructorstaticdemod1;mainstartmainendobjectdestructor3.3.3.2全局类对象73.4友元3.4.1友元函数3.4.1.1友元函数的声明允许一个类授权其它的函数或类访问它的非公有成员。友元声明以friend关键字开头,只能出现在类的定义中。友元不是类的成员,不受访问说明符的影响。一般将类中所有友元关系的声明放在类头之后。
¤语法:friend数据类型函数名(参数标);3.4.1.2友元函数的参数成员函数由对象调用,系统传递this指针使其可以访问对象的成员。友元函数没有this指针,要访问对象的成员,必须将要访问的对象作为参数传递。访问类对象的成员必须加上对象名和成员访问运算符。例如:classData{friendvoidget_val(Data&it,intn,floats);intnum;floatscore;3.4友元8public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};voidData::print(){cout<<num<<“\n”<<score<<“\n”;}voidset_val(Data&it,intn,floats){it.num=n;it.score=s;}intmain(){Datamydata;set_val(mydata,1,67.0);mydata.print();return0;}public:93.4.2友元类3.4.2.1友元类的声明在类的定义体内声明
¤语法:friendclass类名;友元类的所有成员函数都可以访问授权类的成员。友元关系是单向的,A是B的友元,但B不是A的友元。例如:classData{friendclassTeacher;intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};3.4.2友元类10classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};intmain(){Datamydata;Teachertheteacher;theteacher.set_data(mydata,1,87.0);return0;}注意:Teacher类的定义应在Data类之后。3.4.2.2类的成员函数作为友元函数若授权类的友元类中只有一个成员函数要访问授权类的成员,可以只将该成员函数作为授权类的友元函数。classTeacher{11友元类必须在授权类之前定义,但是授权类要在友元类之前作前向声明。只有当一个类的定义已经被看到时,其成员函数才能被声明为另一个类的友元。例如:classData;//声明classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};classData{friendvoidTeacher::set_data(Data&it,intn,floats);intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}};友元类必须在授权类之前定义,但是授权类要在友元类之前作12第4章运算符重载4.1算术运算符+、-可以对任意基本类型进行“+”运算,例如:3+4.7、5+’a’,c语言本身已经重载了该运算符,所以它能够用于int、float、double和其他内部定义类型的变量.如果希望“+”运算可以应用在类对象上,如:data1+data2,需要以函数的形式重新定义“+”运算执行的行为,称为运算符的重载。注意:①只能对用户自定义的数据类型重载运算符,即运算符重载函数的参数至少有一个必须是类的对象或者是对类的对象的引用。②运算符重载实际是定义函数,调用函数时实参不是出现在圆括号内,而是在运算符的旁边,函数名是由关键字operator和其后要重载的运算符符号组成的。③重载不能改变运算符的优先级、结合性。④重载不能改变运算符操作数的个数和运算符本身的含义。⑤不能创建新的运算符,只有现有的运算符才能被重载。
4.1.1作为普通(友元)函数重载
定义:数据类型operator+(参数表){}例如:classdemo{frienddemooperator+(demo&d1,demo&d2);第4章运算符重载13inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demooperator+(demo&d1,demo&d2)//不能返回引用,局部对象temp//在函数结束后内存空间被释放{demotemp(0,0.0);temp.a=d1.a+d2.a;temp.b=d1.b+d2.b;returntemp;}或者:demooperator+(demo&d1,demo&d2){returndemo(d1.a+d2.a,d1.b+d2.b);}调用:对象+对象例如:inta;14demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相当于demo3=operator+(demo1,demo2);demooperator+(demo&d1,demo&d2)希望实现调用:对象+整数demooperator+(demo&d1,intx){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}调用:demodemo1(2,3.2),demo2;demo2=demo1+5;//不能写成demo2=5+demo1;demooperator+(demo&d1,intx)demodemo1(2,3.2),demo2(115希望实现调用:整数+对象demooperator+(intx,demo&d1){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}调用:demodemo1(2,3.2),demo2;demo2=5+demo1;//相当于demo2=operator+(5,demo1);4.1.2作为成员函数重载表示该类对象与另一个操作数进行运算。该类对象作为操作数1。成员函数将指向调用成员函数的类对象的this指针作为第一个参数,所以重载运算符函数需要的参数个数为运算符的操作数个数-1。调用运算符重载函数时,运算符左侧的操作数为调用成员函数的该类对象,右侧的操作数为传递给成员函数的参数。例如:希望实现调用:整数+对象16classdemo{inta;floatb;public:demo(intx,floaty){a=x;b=y;}
demooperator+(demo&it);//相当于demooperator+(demo*this,demo&it);};希望实现调用:对象+对象demodemo::operator+(demo&it){demotemp(0,0.0);temp.a=a+it.a;temp.b=b+it.b;returntemp;}例如:demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相当于demo3=demo1.operator+(demo2);classdemo{17希望实现调用:对象+整数demodemo::operator+(intx){demotemp(0,0.0);temp.a=a+xtemp.b=b+x;returntemp;}例如:demodemo1(2,3.2),demo2;demo2=demo1+5;//相当于demo2=demo1.operator+(5);//不能写成demo2=5+demo1;希望实现调用:整数+对象,不能定义成成员函数。如果运算符的左侧操作数不是类类型而是其它类型,重载运算符函数只能作为友元函数。4.2运算符++、--
4.1.1作为普通(友元)函数重载前置运算符:希望实现调用:对象+整数18定义:数据类型operator++(参数表);例如:classdemo{frienddemo&operator++(demo&it);inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demo&operator++(demo&it){it.a++;it.b++;returnit;}调用:++对象例如:demodemo1(2,3.2);++demo1;//相当于operator++(demo1)定义:数据类型operator++(参数表);19后置运算符:需要增加一个额外的参数例如:demooperator++(demo&it,int){demotemp(it);//调用拷贝构造函数it.a++;it.b++;returntemp;}调用:对象++例如:demodemo1(2,3.2);5+demo1++;//相当于operator++(demo1,int)4.2.2作为成员函数
前置运算符:例如:classdemo{inta;floatb;后置运算符:需要增加一个额外的参数20public:demo(intx,floaty){a=x;b=y;}demo&operator++();};demo&demo::operator++(){a++;b++;return*this;}调用:demodemo1(2,3.2);++demo1;//相当于demo1.operator++()后置运算符:增加一个额外的参数demodemo::operator++(int){demotemp=*this;//调用拷贝构造函数a++;b++;returntemp;}public:21调用:demodemo1(2,3.2);5+demo1++;//相当于demo1.operator++(int)4.3赋值运算符=的重载
运算符()、[]、->,或者任何赋值运算符重载函数必须声明为类的一个成员函数。赋值运算符重载用于“=”两侧的对象都已经存在时,一个类对象向该类的另一个对象赋值。一般在对象的数据成员是指针时用来进行深层复制。例如:demod1(1,4.2);//构造函数demod2=d1;//拷贝构造函数d3=d2;//赋值注意:①确保没有将对象复制给它自身②重新使用被赋值对象中的资源或删除它③从源对象上复制内容到目的对象例如:classTstring{char*str;调用:demodemo1(2,3.2);22intlen;public:Tstring(constchar*p);~Tstring(){delete[]str;}Tstring(constTstring&source);Tstring&operator=(Tstring&it);};Tstring&Tstring::operator=(Tstring&it){if(this==&it)return*this;delete[]str;len=it.len;str=newchar[len]strcpy(str,it.str);return*this;}intlen;23赋值运算符重载也可以用于为一个类对象赋以不是该类类型的值。例如希望实现如下赋值:Tstringcar(“benz”);car=“bmw”;在类定义中增加成员函数:Tstring&operator=(constchar*);Tstring&Tstring::operator=(constchar*cst){if(cst==0){len=0;delete[]str;str=0;}else{len=strlen(cst)+1;delete[]str;str=newchar[len]strcpy(str,it.cst);}return*this;}赋值运算符重载也可以用于为一个类对象赋以不是该类类型的值244.4下标运算符[]的重载可以重载用于检查数组的下标是否越界定义:operator[](intindex){}调用:对象[下标]出现在赋值运算符左侧,应该返回左值(指针、引用),出现在赋值运算符右侧,应该返回元素的值,但是函数只有一种返回类型,只有返回引用可以作为左值。例如:classintarray{intsize;int*ip;public:intarray(unsignedmaxsize){size=maxsize;ip=newint[size];}~intarray(){delete[]ip;}4.4下标运算符[]的重载25int&operator[](index);};int&intarray::operator[](index){if(index<0||index>=size){cout<<”outofrange!\n”;exit(1);}returnip[index];}intmain(){intsize=100;intarrya(size);for(inti=0;i<size;i++)a[i]=i;…}int&operator[](in264.5成员访问运算符->的重载
赋予类类型类似指针的行为定义:数据类型operator->(){}调用:对象->成员,相当于:(对象.operator->())->成员注意:①对->的重载必须返回指向类对象的指针②->后的成员必须是返回的指针可以访问的成员③在返回的指针上再应用->以访问该成员。例如:
4.5成员访问运算符->的重载27classfoo{public:intm;};classz{public:foof;foo*operator->(){return&f;}};intmain(){zz1;z1->m=0;}//可用于访问对象成员的成员4.6函数调用运算符()的重载重载了()运算符的对象称为functionobject,可作为函数来使用classfoo{28定义:数据类型operator()(参数表){}调用:类对象(参数表)例如:classlessthan{intval;public:lessthan(intx){val=x;}booloperator()(intvalue)const;};boollessthan::operator()(intvalue)const{returnvalue<val;}intmain(){lessthanit(10);inta=5;if(it(a))cout<<”lessthan”;return0;}定义:数据类型operator()(参数表){}29例如:classabsint{public:intoperator()(intvalue){intresult=value<0?-value:value;returnresult;}};intmain(){absintitabs;inta;cin>>a;cout<<itabs(a);return0;}
4.7用户定义的转换
隐式调用例如:classabsint{304.7.1构造函数作为转换函数只有一个基本类型参数(可以还有其它缺省参数)的构造函数,可以作为类型转换构造函数,实现转换:基本类型类类型使用构造函数执行隐式转换时,构造函数参数类型不必与被转换值的类型完全一致,编译器会在调用构造函数执行用户定义的转换之前,对实参应用标准转换。例如:classdemo{frienddemooperator+(demo&d1,demo&d2);inta;public:demo(intx=0)//intdemo{a=x;}};intmain(){demod1(3),d2;d2=5+d1;//5demo,相当于demotemp(5);d2=temp+d1;d2=d1+4.2;//4.2intdemo4.7.1构造函数作为转换函数31类A的构造函数将类B的对象(或引用)作为它的单个参数,可以作为类型转换构造函数,实现转换:B类类型A类类型例如:classB{public:B(){}};classA{public:A(B&b){}};voidfun(Aa){}intmain(){Bb1;fun(b1);}//相当于Atemp(b1);//fun(temp);调用构造函数A(b1)把b1转换成A类型的值。编译器调用构造函数创建一个A类型临时对象,将临时对象的值传递给fun()函数。类A的构造函数将类B的对象(或引用)作为它的单个参数324.7.2类型转换运算符重载(转换函数)
定义:operator类型(){}实现类类型和转换函数中指定的类型之间的转换注意:①转换函数不允许定义返回类型,但必须有返回值。②只能定义成类的成员函数,转换函数中指定的类型可以是内置类型、类类型。例如:classdemo{demooperator+(demo&d1,demo&d2);inta;floatb;public:demo(intx,floaty){a=x;b=y;}operatorint(){returna;}
};4.7.2类型转换运算符重载(转换函数)33intmain(){demod1(4,7.5);inta=5+d1;//调用d1.operatorint()将d1intdoublef=d1+3.9;//调用d1.operatorint()将d1intdoublecout<<a<<”\n”<<f<<”\n”;}4.7.3构造函数和转换函数的相互影响
转换函数执行后,可以用标准转换把转换函数的结果转换成目标类型;在构造函数执行转换之前,可以用标准转换把要转换的值转换成构造函数参数的类型。现类型目标类型转换序列:标准转换用户定义的转换标准转换当不只一个转换序列可以被应用时,编译器必须选择最好的序列执行转换。标准转换成为选择的依据。若所有的转换都一样好,则出现二义性。例如:classdemo{inta;public:intmain()34demo(intx=0)//intdemo{a=x;}operatorint(){returna;}operatorfloat(){returna;}};intmain(){demod1(3);longv=d1;}//调用d1.operatorint()将d1intlong//调用d1.operatorfloat()将d1floatlongdemo(intx=0)//intde353.3静态类成员3.3.1静态数据成员
希望数据为类的所有对象共享,而不是每个类对象维持一个独立的数据成员。例如:计数在程序的任意一点一共创建了多少个此类类型的对象。静态数据成员对每个类类型只有一个拷贝,由该类对象共享访问。非静态数据成员对每个类对象都有自己的拷贝。可以实现信息隐藏,可以是private成员。3.3.1.1类定义内声明在类体中数据成员声明前加上static关键字,使该数据成员成为静态的例如:classstudent{intnum;floatscore;public:staticfloatpassmark;staticintpassnum;3.3静态类成员36student(inta,floatf){num=a;score=f;}};3.3.1.2类定义外初始化
¤语法:数据类型类名::数据成员名=初值;注意:①如果没有初值,系统自动初始化为0。②整型const静态数据成员可以在类定义体内用常量值初始化,但仍要在类定义体外定义该数据成员且不能再指定初始值。③静态数据成员的初始化不应该放在头文件中。一般放在类定义之后,main函数之前。产生类对象之前可能用到静态数据成员。例如:classAccout{{staticconstintnamesize=16;staticconstcharname[namesize];};constintAccout::namesize;constcharAccout::name[namesize]=”savingaccount”;3.3.1.3静态数据成员的访问student(inta,flo37类的成员函数中访问:用静态数据成员名直接访问非成员函数中访问public静态数据成员:类名::静态数据成员名对象.静态数据成员名指向对象的指针->静态数据成员名例如:计数已创建对象的数目classData{intnum;floatscore;public:staticintobject;Data(inta,floatf):num(a),score(f){object++;}~Data(){object--;}};类的成员函数中访问:用静态数据成员名直接访问383.3.2静态成员函数
希望在产生对象之前访问private静态数据成员3.3.2.1声明与定义在类内普通成员函数声明前加上static关键字,在类外定义前不需再加static。注意:静态成员函数没有this指针,不能访问类的非静态成员,只能访问类的静态数据成员或是调用其它静态成员函数。3.3.2.2调用类名::静态函数名(参数表);对象.静态函数名(参数表);指向对象的指针->静态函数名(参数表);例如:classSmall{staticintobject;public:Small(){object++;}staticintget_n(){returnobject;}3.3.2静态成员函数39~Small(){object--;}};intSmall::object=0;intmain(){intn;n=Small::get_n();//…}3.3.3全局、静态局部类对象
3.3.3.1局部静态类对象在函数或复合语句内,用static关键字定义的对象。例如:intfun(){staticData(1,89.0);return0;}代码执行过程中第一次遇到该对象定义时,构造函数被调用,程序运行中仅调用一次;在程序运行结束前,调用析构函数,也只调用一次。例如:~Small(){o40classdemo{public:demo(){cout<<”objectconstructor\n”;}~demo(){cout<<”objectdestructor\n”}};voidfun(){staticdemod1;}intmain(){cout<<"mainstart\n";fun();cout<<"again\n";fun();输出:mainstartcout<<"mainend\n";}objectconstructoragainmainendobjectdestructorclassdemo{413.3.3.2全局类对象在函数外定义的对象。构造函数在main函数执行前被调用,析构函数在程序运行结束前调用。例如:classdemo{public: demo(){cout<<"objectconstructor\n";} ~demo(){cout<<"objectdestructor\n";}};intmain(){ cout<<"mainstart\n";cout<<"mainend\n";return0;}输出:objectconstructorstaticdemod1;mainstartmainendobjectdestructor3.3.3.2全局类对象423.4友元3.4.1友元函数3.4.1.1友元函数的声明允许一个类授权其它的函数或类访问它的非公有成员。友元声明以friend关键字开头,只能出现在类的定义中。友元不是类的成员,不受访问说明符的影响。一般将类中所有友元关系的声明放在类头之后。
¤语法:friend数据类型函数名(参数标);3.4.1.2友元函数的参数成员函数由对象调用,系统传递this指针使其可以访问对象的成员。友元函数没有this指针,要访问对象的成员,必须将要访问的对象作为参数传递。访问类对象的成员必须加上对象名和成员访问运算符。例如:classData{friendvoidget_val(Data&it,intn,floats);intnum;floatscore;3.4友元43public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};voidData::print(){cout<<num<<“\n”<<score<<“\n”;}voidset_val(Data&it,intn,floats){it.num=n;it.score=s;}intmain(){Datamydata;set_val(mydata,1,67.0);mydata.print();return0;}public:443.4.2友元类3.4.2.1友元类的声明在类的定义体内声明
¤语法:friendclass类名;友元类的所有成员函数都可以访问授权类的成员。友元关系是单向的,A是B的友元,但B不是A的友元。例如:classData{friendclassTeacher;intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};3.4.2友元类45classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};intmain(){Datamydata;Teachertheteacher;theteacher.set_data(mydata,1,87.0);return0;}注意:Teacher类的定义应在Data类之后。3.4.2.2类的成员函数作为友元函数若授权类的友元类中只有一个成员函数要访问授权类的成员,可以只将该成员函数作为授权类的友元函数。classTeacher{46友元类必须在授权类之前定义,但是授权类要在友元类之前作前向声明。只有当一个类的定义已经被看到时,其成员函数才能被声明为另一个类的友元。例如:classData;//声明classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};classData{friendvoidTeacher::set_data(Data&it,intn,floats);intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}};友元类必须在授权类之前定义,但是授权类要在友元类之前作47第4章运算符重载4.1算术运算符+、-可以对任意基本类型进行“+”运算,例如:3+4.7、5+’a’,c语言本身已经重载了该运算符,所以它能够用于int、float、double和其他内部定义类型的变量.如果希望“+”运算可以应用在类对象上,如:data1+data2,需要以函数的形式重新定义“+”运算执行的行为,称为运算符的重载。注意:①只能对用户自定义的数据类型重载运算符,即运算符重载函数的参数至少有一个必须是类的对象或者是对类的对象的引用。②运算符重载实际是定义函数,调用函数时实参不是出现在圆括号内,而是在运算符的旁边,函数名是由关键字operator和其后要重载的运算符符号组成的。③重载不能改变运算符的优先级、结合性。④重载不能改变运算符操作数的个数和运算符本身的含义。⑤不能创建新的运算符,只有现有的运算符才能被重载。
4.1.1作为普通(友元)函数重载
定义:数据类型operator+(参数表){}例如:classdemo{frienddemooperator+(demo&d1,demo&d2);第4章运算符重载48inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demooperator+(demo&d1,demo&d2)//不能返回引用,局部对象temp//在函数结束后内存空间被释放{demotemp(0,0.0);temp.a=d1.a+d2.a;temp.b=d1.b+d2.b;returntemp;}或者:demooperator+(demo&d1,demo&d2){returndemo(d1.a+d2.a,d1.b+d2.b);}调用:对象+对象例如:inta;49demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相当于demo3=operator+(demo1,demo2);demooperator+(demo&d1,demo&d2)希望实现调用:对象+整数demooperator+(demo&d1,intx){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}调用:demodemo1(2,3.2),demo2;demo2=demo1+5;//不能写成demo2=5+demo1;demooperator+(demo&d1,intx)demodemo1(2,3.2),demo2(150希望实现调用:整数+对象demooperator+(intx,demo&d1){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}调用:demodemo1(2,3.2),demo2;demo2=5+demo1;//相当于demo2=operator+(5,demo1);4.1.2作为成员函数重载表示该类对象与另一个操作数进行运算。该类对象作为操作数1。成员函数将指向调用成员函数的类对象的this指针作为第一个参数,所以重载运算符函数需要的参数个数为运算符的操作数个数-1。调用运算符重载函数时,运算符左侧的操作数为调用成员函数的该类对象,右侧的操作数为传递给成员函数的参数。例如:希望实现调用:整数+对象51classdemo{inta;floatb;public:demo(intx,floaty){a=x;b=y;}
demooperator+(demo&it);//相当于demooperator+(demo*this,demo&it);};希望实现调用:对象+对象demodemo::operator+(demo&it){demotemp(0,0.0);temp.a=a+it.a;temp.b=b+it.b;returntemp;}例如:demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相当于demo3=demo1.operator+(demo2);classdemo{52希望实现调用:对象+整数demodemo::operator+(intx){demotemp(0,0.0);temp.a=a+xtemp.b=b+x;returntemp;}例如:demodemo1(2,3.2),demo2;demo2=demo1+5;//相当于demo2=demo1.operator+(5);//不能写成demo2=5+demo1;希望实现调用:整数+对象,不能定义成成员函数。如果运算符的左侧操作数不是类类型而是其它类型,重载运算符函数只能作为友元函数。4.2运算符++、--
4.1.1作为普通(友元)函数重载前置运算符:希望实现调用:对象+整数53定义:数据类型operator++(参数表);例如:classdemo{frienddemo&operator++(demo&it);inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demo&operator++(demo&it){it.a++;it.b++;returnit;}调用:++对象例如:demodemo1(2,3.2);++demo1;//相当于operator++(demo1)定义:数据类型operator++(参数表);54后置运算符:需要增加一个额外的参数例如:demooperator++(demo&it,int){demotemp(it);//调用拷贝构造函数it.a++;it.b++;returntemp;}调用:对象++例如:demodemo1(2,3.2);5+demo1++;//相当于operator++(demo1,int)4.2.2作为成员函数
前置运算符:例如:classdemo{inta;floatb;后置运算符:需要增加一个额外的参数55public:demo(intx,floaty){a=x;b=y;}demo&operator++();};demo&demo::operator++(){a++;b++;return*this;}调用:demodemo1(2,3.2);++demo1;//相当于demo1.operator++()后置运算符:增加一个额外的参数demodemo::operator++(int){demotemp=*this;//调用拷贝构造函数a++;b++;returntemp;}public:56调用:demodemo1(2,3.2);5+demo1++;//相当于demo1.operator++(int)4.3赋值运算符=的重载
运算符()、[]、->,或者任何赋值运算符重载函数必须声明为类的一个成员函数。赋值运算符重载用于“=”两侧的对象都已经存在时,一个类对象向该类的另一个对象赋值。一般在对象的数据成员是指针时用来进行深层复制。例如:demod1(1,4.2);//构造函数demod2=d1;//拷贝构造函数d3=d2;//赋值注意:①确保没有将对象复制给它自身②重新使用被赋值对象中的资源或删除它③从源对象上复制内容到目的对象例如:classTstring{char*str;调用:demodemo1(2,3.2);57intlen;public:Tstring(constchar*p);~Tstring(){delete[]str;}Tstring(constTstring&source);Tstring&operator=(Tstring&it);};Tstring&Tstring::operator=(Tstring&it){if(this==&it)return*this;delete[]str;len=it.len;str=newchar[len]strcpy(str,it.str);return*this;}intlen;58赋值运算符重载也可以用于为一个类对象赋以不是该类类型的值。例如希望实现如下赋值:Tstringcar(“benz”);car=“bmw”;在类定义中增加成员函数:Tstring&operator=(constchar*);Tstring&Tstring::operator=(constchar*cst){if(cst==0){len=0;delete[]str;str=0;}else{len=strlen(cst)+1;delete[]str;str=newchar[len]strcpy(str,it.cst);}
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 延安大学西安创新学院《经济应用文写作》2021-2022学年第一学期期末试卷
- 延安大学《中国古代文学(二)》2022-2023学年第一学期期末试卷
- 草坪场地租赁合同三篇
- 管线切改安全管理措施
- 学习与心理健康的结合计划
- 用户体验在图书馆服务中的影响计划
- 信阳师范大学《数据库原理及应用》2021-2022学年第一学期期末试卷
- 信阳师范大学《人工智能计算》2023-2024学年第一学期期末试卷
- 游戏学习在幼儿园的实施意义计划
- 建立良好习惯成就卓越计划
- 三级包装设计师理论考试复习题库(含答案)
- 2023-2024学年九年级上学期期末试卷及答案
- 《网络营销》试题及答案2
- TSG 03-2015《特种设备事故报告和调查处理导则》
- 村级民兵连长述职报告
- 《工程经济与管理》教学大纲
- 建筑信息模型技术员技能竞赛考试题库备赛500题(含答案)
- 图解2024年全国民族团结进步表彰大会
- 糖尿病酮症酸中毒诊疗指南中国2型糖尿病防治指南(2020年版)
- 《心系国防 强国有我》 课件-2024-2025学年高一上学期开学第一课国防教育主题班会
- 专升本合同协议模板
评论
0/150
提交评论