一、重载双目运算符
例1 重载算数运算符,用于两个字符串的比较
注:
1)比较规则:调用int strcmp(const char *str1, const char *str2)函数,按照ASCII码表从首字母开始比较str1和str2的值。
2)因为算数运算符需要两个对象(左、右各一个操作数),因此只能用友元函数形式。
3)运算符重载可以嵌套使用。
cpp
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
class String
{
public:
String( ){p=NULL;}
String(char *str); //重载构造函数,为类型为字符串指针的数据成员分配空间
~String(); //析构函数,释放空间
friend string operator>(String &s1, String &s2);
friend string operator<(String &s1, String &s2);
friend string operator==(String &s1, String &s2);
friend string operator>=(String &s1, String &s2);
friend string operator<=(String &s1, String &s2);
friend string operator!=(String &s1, String &s2);
void display( );
private:
char *p;
};
String::String(char *str)
{
p = new char[strlen(str)+1];
strcpy(p, str);
}
void String::display( )
{
cout<<"The string is: "<<p<<endl;
}
String::~String()
{
delete p;
}
string operator>(String &s1,String &s2) //strcmp按照ASCII码表,从字符串首字母开始依次比较,直至有差异;
{
if(strcmp(s1.p,s2.p)>0)
return "YES";
else
return "NO";
}
string operator<(String &s1,String &s2)
{
if(strcmp(s1.p,s2.p)<0)
return "YES";
else
return "NO";
}
string operator==(String &s1, String &s2)
{
if(strcmp(s1.p,s2.p)==0)
return "YES";
else
return "NO";
}
string operator>=(String &s1, String &s2)
{
if((s1<s2) == "YES") //运算符重载嵌套
return "NO";
else
return "YES";
}
string operator<=(String &s1, String &s2)
{
if((s1>s2) == "YES") //运算符重载嵌套
return "NO";
else
return "YES";
}
string operator!=(String &s1, String &s2)
{
if((s1==s2) == "YES") //运算符重载嵌套
return "NO";
else
return "YES";
}
int main()
{
String s1("a");
String s2("b");
s1.display( );
s2.display( );
string a1 = "NULL";
a1 = (s1>s2);
cout<<"If s1 > s2 established? The answer is: "<<a1<<endl;
a1 = (s1<s2);
cout<<"If s1 < s2 established? The answer is: "<<a1<<endl;
a1 = (s1==s2);
cout<<"If s1 == s2 established? The answer is: "<<a1<<endl;
a1 = (s1>=s2);
cout<<"If s1 >= s2 established? The answer is: "<<a1<<endl;
a1 = (s1<=s2);
cout<<"If s1 <= s2 established? The answer is: "<<a1<<endl;
a1 = (s1!=s2);
cout<<"If s1 != s2 established? The answer is: "<<a1<<endl;
return 0;
}
例2 重载复合赋值运算符+=
cpp
#include <iostream>
using namespace std;
class Complex{
public:
Complex()
{
real=0;
imag=0;
}
Complex(double r,double i)
{
real=r;
imag=i;
}
Complex operator += (const Complex & c);
void display( );
private:
double real;
double imag;
};
Complex Complex::operator += (const Complex & c)
{
real += c.real; //this->real += c.real;
imag += c.imag; //this->imag += c.imag;
return *this;
}
void Complex::display( )
{
cout<<"("<<real<<","<<imag<<"i)"<<endl;
}
int main( )
{
Complex c1(3,4),c2(-3,-4);
c1+=c2; //相当于c1.operator+=(c2);
cout<<"c1 = ";
c1.display();
return 0;
}
二、重载单目运算符
当使用成员函数方式 作为单目运算符的重载函数时,由于成员函数已将本类对象作为一个默认参数(class *this),且单目运算符仅一个操作数,因此入参直接省略;所以,不用友元函数形式了。
例3 重载~取反运算符,实现分数类对象的倒数
cpp
#include <iostream>
#include <cmath>
using namespace std;
class CFraction
{
private:
int nume; // 分子 numerator
int deno; // 分母 denominator
public:
CFraction(int nu=0,int de=1):nume(nu),deno(de) {} //构造函数
CFraction operator+(const CFraction &c); //+双目运算符重载函数,实现分数相加
CFraction operator-(const CFraction &c); //-双目运算符重载函数,实现分数相减
CFraction operator~(); //-单目运算符重载函数,实现分数取反
void simplify();
void display();
};
CFraction CFraction:: operator+(const CFraction &c) //分数加法,双目+运算符重载
{
CFraction t;
t.nume=nume*c.deno+c.nume*deno; //通分 分子
t.deno=deno*c.deno; //通分 分母
t.simplify();
return t;
}
CFraction CFraction:: operator-(const CFraction &c) //分数减法,双目-运算符重载
{
CFraction t;
t.nume=nume*c.deno-c.nume*deno; //通分 分子
t.deno=deno*c.deno; //通分 分母
t.simplify();
return t;
}
CFraction CFraction:: operator~() //分数取倒数,单目~运算符重载
{
CFraction x;
x.nume=deno;
x.deno=nume;
return x;
}
void CFraction::simplify()
{
int m,n,r;
m=fabs(nume); //分子 取绝对值
n=fabs(deno); //分母 取绝对值
while(m%n) // 求m,n的最大公约数r
{
r=m%n;
m=n;
n=r; //r即为最大公约数
}
deno/=n; // 通分 分母
nume/=n; // 通分 分子
if (deno<0) // 将分母转化为正数
{
deno=-deno;
nume=-nume;
}
}
void CFraction::display()
{
cout<<nume<<"/"<<deno<<endl;
}
int main()
{
CFraction CF1(1,2),CF2(1,3),CF3,CF4,CF5,CF6;
CF1.display();
CF2.display();
cout<<"=============="<<endl;
CF6 = CF1 + CF2; //CF6 = CF1.operator+(CF2);
CF6.display();
cout<<"=============="<<endl;
CF3 = CF2 - CF1; //CF3 = CF2.operator-(CF1);
CF3.display();
CF4 = CF1 - CF2; //CF4 = CF1.operator-(CF2);
CF4.display();
cout<<"=============="<<endl;
CF5 = ~CF4; //CF5 = CF4.operator~();
CF5.display();
return 0;
}
例4 重载前置++运算符,实现时钟加一秒
cpp
#include <iostream>
#include <cmath>
using namespace std;
class Time
{
public:
Time( ){hour=0;minute=0;sec=0;}
Time(int h,int m,int s): hour(h),minute(m),sec(s){ }
Time operator++( );
void display( )
{
cout<<hour<<":";
cout<<minute<<":";
cout<<sec<<endl;
}
private:
int hour;
int minute;
int sec;
};
Time Time::operator++( )
{
if((++sec)>=60)
{
sec-=60;
++minute;
}
if((minute)>=60)
{
minute-=60;
++hour;
}
if((hour)>=24)
{
hour = minute =sec =0;
}
return *this; //注意:返回当前最新对象
}
int main()
{
Time t1(22,33,59);
t1.display( );
++t1;
t1.display( );
return 0;
}
例5 重载后置++运算符(特殊)
注意:前置++与后置++在声明、定义时的形式不同
cpp
Time operator++( ); //前置++
Time operator++(int); //后置++
完整代码:
cpp
#include <iostream>
#include <cmath>
using namespace std;
class Time
{
public:
Time( ){hour=0;minute=0;sec=0;}
Time(int h,int m,int s): hour(h),minute(m),sec(s){ }
Time operator++(int); //C++特别规定,如果后置++则需要在入参中,明确标出参数类型
void display()
{
cout<<hour<<":";
cout<<minute<<":";
cout<<sec<<endl;
}
private:
int hour;
int minute;
int sec;
};
Time Time::operator++(int) //后置++
{
Time temp(*this); //先复制当前对象到temp
sec++; //后置++
if(sec>=60)
{
sec-=60; //sec = sec-60
++minute;}
if(minute>=60)
{
minute-=60;
++hour;}
if(hour>=24)
{
hour-=24;
hour = minute =sec =0;
}
cout<<temp.sec<<endl; //之前对象的sec
cout<<this->sec<<endl; //当前对象的sec
return temp; //注意:返回之前的对象,而不是当前对象!
}
int main()
{
Time t1(22,33,56);
t1.display( );
t1++;
t1.display( );
t1++;
t1.display( );
return 0;
}
三、重载流插入运算符和
1、在C++中,cin属于istream类的对象,cout属于ostream类的对象;
2、>>和<<是移位运算符,进行了重载;
(一)<<运算符重载函数的形式
cpp
ostream &operator<<(ostream&, const 自定义类&);
1)参数1:ostream&
2)参数2:要输出的自定义类
3)函数类型:ostream&
注:
由于有两个当前类外的入参,因此只能不能使用成员函数形式,只能友元或普通函数。返回类型要加&.
例6 重载流插入运算符
cpp
#include <iostream>
#include <cmath>
using namespace std;
#include <iostream>
using namespace std;
class Complex
{
public:
Complex( ){real=0;imag=0;} //构造函数
Complex(double r,double i){real=r;imag=i;} //重载构造函数带参
Complex operator + (Complex &c2); //+运算符重载函数
friend ostream& operator << (ostream&, const Complex&); //<<输出流运算符重载函数,返回类型加&
private:
double real;
double imag;
};
Complex Complex::operator + (Complex &c2)
{
return Complex(real+c2.real,imag+c2.imag);
}
ostream& operator << (ostream& output,const Complex& c) //
{
output<<"("<<c.real<<"+"<<c.imag<<"i)";
return output;
}
int main( )
{
Complex c1(2,4),c2(6,10),c3;
cout<<c1<<c2<<endl; //等同于operator<<(operator<<(cout,c1),c2),运算符重载嵌套!
c3=c1+c2;
cout<<c1<<'+'<<c2<<'='<<c3<<endl;
return 0;
}