1.C++运算符重载的作用
使对象的运算表现得和编译器内置类型一样。如我们想输出一个Complex,希望输出它的实部和虚部,那么我们只需要对<<进行重载即可。为什么不重载cout?因为cout是ostream类型的对象,系统已经给我们定义好了的,我们很难去对它ostream类进行重载。
2.几个例子加深对运算符重载的理解
(1)实现一个简单的Complex类
usingnamespacestd; //// 复数类//classCComplex{ public: // CComplex() CComplex(20) CComplex(30,30)CComplex(intr=0, inti=0) :mreal(r), mimage(i) { cout<<"CComplex(int r = 0, int i = 0)"<<endl; } //指导编译器怎么做类对象的加法操作//CComplex operator+(const CComplex& src)//{// /*CComplex comp;// comp.mreal = this->mreal + src.mreal;// comp.mimage = this->mimage + src.mimage;// return comp;*/// return CComplex(this->mreal + src.mreal, this->mimage + src.mimage);//}voidshow() { cout<<"real:"<<mreal<<"image:"<<mimage<<endl; } CComplexoperator++(int) { returnCComplex(mreal++, mimage++); } CComplex&operator++() { mreal+=1; mimage+=1; return*this; } voidoperator+=(constCComplex&src) { mreal+=src.mreal; mimage+=src.mimage; } private: intmreal; intmimage; friendCComplexoperator+(constCComplex&comp, constCComplex&src); friendostream&operator<<(ostream&out, CComplexconst&src); }; CComplexoperator+(constCComplex&comp,constCComplex&src) { /*CComplex comp;comp.mreal = this->mreal + src.mreal;comp.mimage = this->mimage + src.mimage;return comp;*/returnCComplex(comp.mreal+src.mreal, comp.mimage+src.mimage); } ostream&operator<<(ostream&out, CComplexconst&src) { out<<"mreal:"<<src.mreal<<"mimage:"<<src.mimage<<endl; returnout; } intmain(void) { CComplexcomp1(10, 10); CComplexcomp2(20, 20); // comp1.operator+(com2) 加法运算符的重载函数//CComplexcomp3=comp1+comp2; comp3.show(); CComplexcomp4=comp1+10;//comp1.operator+(10);comp4.show(); //编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法,就在全局作用域找合适的运算符重载函数 ::operator+(30,comp1)CComplexcomp5=10+comp1; comp5.show(); //CComplex operator(int){}comp5=comp1++;//++ --单目运算符 operator++()前置++ operator++(int)后置++comp1.show(); comp5.show(); //CComplex operator(){}comp5=++comp1; comp1.show(); comp5.show(); /*CComplex* c = &(comp1++);*//*comp1++.operator=(comp5);*//*comp1.show();*/comp1+=comp2; comp1.show(); cout<<comp1; return0; }
(2)实现一个简单的string类
usingnamespacestd; //自己实现一个字符串classMyString{ public: MyString(constchar*p=nullptr) { if (p!=nullptr) { _pstr=newchar[strlen(p) +1]; strcpy(_pstr, p); } else { _pstr=newchar[1]; _pstr[0] ='\0'; } } MyString(constMyString&str) { _pstr=newchar[strlen(str._pstr) +1]; strcpy(_pstr, str._pstr); } ~MyString() { delete[]_pstr; _pstr=nullptr; } MyString&operator+(constMyString&str) { if (this==&str)//排除自赋值 { return*this; } delete[]_pstr; _pstr=newchar[strlen(str._pstr) +1]; strcpy(_pstr, str._pstr); return*this; } booloperator>(constMyString&str) const { returnstrcmp(_pstr, str._pstr) >0; } booloperator<(constMyString&str) const { returnstrcmp(_pstr, str._pstr) <0; } booloperator=(constMyString&str) const { returnstrcmp(_pstr, str._pstr) ==0; } intlength()const { returnstrlen(_pstr); } char&operator[](intindex) { return_pstr[index]; } constchar&operator[] (intindex)const { return_pstr[index];//不能作为左值 } constchar*c_str()const { return_pstr; } private: char*_pstr; friendostream&operator<<(ostream&out, constMyString&str); friendMyStringoperator+(constMyString&str1, constMyString&str2); }; MyStringoperator+(constMyString&str1, constMyString&str2) { char*ptmp=newchar[strlen(str1._pstr) +strlen(str2._pstr) +1]; strcpy(ptmp, str1._pstr); strcat(ptmp, str2._pstr); MyStringtmp(ptmp); delete[]ptmp; returntmp; /*return MyString(ptmp);*/} ostream&operator<<(ostream&out, constMyString&str) { out<<str._pstr; returnout; } intmain(void) { MyStringstr1; MyStringstr2="aaa"; MyStringstr3="bbb"; MyStringstr4=str2+str3; MyStringstr5=str2+"ccc"; MyStringstr6="ddd"+str2; cout<<"str6"<<str6<<endl; if (str5>str6) { cout<<str5<<">"<<str6<<endl; } else { cout<<str6<<"<"<<str6<<endl; } intlen=str6.length(); for (inti=0; i<len; ++i) { cout<<str6[i] <<" "; } cout<<endl; charbuf[1024] = { 0 }; strcpy(buf, str6.c_str()); return0; }