一.运算符重载的两种形式
运算符重载为类的成员函数或类的友元函数
1.区别:
成员函数具有this 指针,友元函数没有this指针
2.联系:不管是成员函数还是友元函数重载,运算符的:
使用方法相同。
传递参数的方式不同,实现代码不同,应用场合也不同 。
二. 用成员函数重载运算符
1.当一元运算符的操作数,或者二元运算符的左操作数是类的对象时,定义重载算符函数为成员函数。
2. 二元运算符op
如果要重载op 为类的成员函数,使之能够实现表达式oprd1 op oprd2,其中oprd1 为A 类对象,则op 应被重载为A 类的成员函数,形参类型应该是oprd2 所属的类型。
经重载后,表达式oprd1 op oprd2 相当于oprd1.operator op(oprd2)
例 将“+”、“-”运算重载为复数类的成员函数
#include<iostream>
using namespace std;
class Complex //复数类声明
{
public:
Complex(double r=0.0,double i=0.0)
{
real=r;
imag=i;
}
Complex operator + (Complex c2); //+重载为成员函数
Complex operator - (Complex c2); //-重载为成员函数
void display(); //输出复数
private: //私有数据成员
double real; //复数实部
double imag; //复数虚部
};
Complex Complex::operator + (Complex c2) //重载函数实现
{
Complex c;
c.real=real+c2.real;
c.imag=imag+c2.imag;
return Complex(c.real,c.imag);
}
Complex Complex::operator - (Complex c2) //重载函数实现
{
Complex c;
c.real=real-c2.real;
c.imag=imag-c2.imag;
return Complex(c.real,c.imag);
}
void Complex::display()
{
cout<<"("<<real<<","<<imag<<")"<<endl;
}
int main() //主函数
{
Complex c1(5,4),c2(2,10),c3; //声明复数类的对象
cout<<"c1=";
c1.display();
cout<<"c2=";
c2.display();
c3=c1-c2; //使用重载运算符完成复数减法
cout<<"c3=c1-c2=";
c3.display();
c3=c1+c2; //使用重载运算符完成复数加法
cout<<"c3=c1+c2=";
c3.display();
}
3.前置运算符和后置运算符
增1减1运算符是一元运算符。它们又有前置和后置两种。为了区分这两
种运算,将后置运算视为二元运算符。表达式 obj++或obj–
被看作为: obj++0或obj–0
若前置一元运算符重载为有返回值
#include<iostream>
using namespace std;
class Clock //时钟类声明
{
public:
Clock(int NewH=0, int NewM=0, int NewS=0)
{
Hour=NewH;
Minute=NewM;
Second=NewS;
}
void ShowTime()
{
cout<< Hour<<":"<<Minute<<":"<<Second<<endl;
}
Clock& operator ++(); //前置一元运算符重载
Clock operator ++(int); //后置一元运算符重载
private:
int Hour,Minute,Second;
};
Clock& Clock::operator ++() //前置一元运算符重载函数有返回值
{
Second++;
if(Second>=60)
{
Second=Second-60;
Minute++;
if(Minute>=60)
{
Minute=Minute-60;
Hour++;
Hour=Hour%24;
}
}
return *this;
}
void main()
{
Clock myClock(23,59,59);
cout<<"First time output:";
myClock.ShowTime();
cout<<"Show myClock++:";
(myClock++).ShowTime();
cout<<"Show ++myClock:";
(++myClock).ShowTime();
}
当为后置时
Clock Clock::operator ++(int)
{
Clock old=*this;
Second++;
if(Second>=60)
{
Second=Second-60;
Minute++;
{
Minute=Minute-60;
Hour++;
Hour=Hour%24;
}
}
return old;
}
若前置一元运算符重载为无返回值
#include<iostream>
using namespace std;
class Clock //时钟类声明
{
public:
Clock(int NewH=0, int NewM=0, int NewS=0)
{
Hour=NewH;
Minute=NewM;
Second=NewS;
}
void ShowTime()
{
cout<< Hour<<":"<<Minute<<":"<<Second<<endl;
}
void operator ++(); //前置一元运算符重载
Clock operator ++(int); //后置一元运算符重载
private:
int Hour,Minute,Second;
};
void Clock::operator ++() //前置一元运算符重载函数无返回值
{
Second++;
if(Second>=60)
{
Second=Second-60;
Minute++;
if(Minute>=60)
{
Minute=Minute-60;
Hour++;
Hour=Hour%24;
}
}
}
void main()
{
Clock myClock(23,59,59);
cout<<"First time output:";
myClock.ShowTime();
cout<<"Show myClock++:";
(myClock++).ShowTime();
cout<<"Show ++myClock:";
}
若为后置时
Clock Clock::operator ++(int)
{
Clock old=*this;
Second++;
if(Second>=60)
{
Second=Second-60;
Minute++;
if(Minute>=60)
{
Minute=Minute-60;
Hour++;
Hour=Hour%24;
}
}
return old;
}
三.用友元函数重载运算符
1.如果需要重载一个运算符,使之能够用于操作某类对象的私有成员,可以此将运算符重载为该类的友元函数。
2.函数的形参代表依自左至右次序排列的各操作数。
3.在第一个参数需要隐式转换的情形下,使用友元函数重载运算符是正确的选择
4.友元函数没有this 指针,所需操作数都必须在参数表显式声明,很容易实现类型的隐式转换
例 复数运算
#include<iostream>
using namespace std;
class Complex
{
public:
Complex( double r =0, double i =0 )
{
Real = r ;
Imag = i ;
}
Complex(int a)
{
Real = a ;
Imag = 0 ;
}
void print() const ;
friend Complex operator+(const Complex &c1, const Complex &c2 ) ;
friend Complex operator-(const Complex &c1, const Complex &c2 ) ;
friend Complex operator- ( const Complex & c ) ;
//前置一元运算符重载
private:
double Real, Imag ;
};
Complex operator + ( const Complex & c1, const Complex & c2 )
{
double r = c1.Real + c2.Real ;
double i = c1.Imag+c2.Imag ;
return Complex ( r, i ) ;
}
Complex operator - ( const Complex & c1, const Complex & c2 )
{
double r = c1.Real - c2.Real ;
double i = c1.Imag - c2.Imag ;
return Complex ( r, i ) ;
}
Complex operator- ( const Complex & c )
{
return Complex ( -c.Real, - c.Imag ) ;
}
void Complex :: print() const
{
cout << '(' << Real << " , " << Imag << ')' << endl ;
}
int main()
{
Complex c1( 2.5,3.7 ), c2( 4.2, 6.5 ) ;
Complex c ;
c.print() ;
c = 25 + c2 ;
c = c1 - c2 ;
c.print() ;
c = c2 + 25 ;
c.print() ;
c = - c1 ;
c.print() ;
}
四.成员运算符函数与友元运算符函数的比较