用成员或友元函数重载运算符

一.运算符重载的两种形式

运算符重载为类的成员函数或类的友元函数
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() ;

}

四.成员运算符函数与友元运算符函数的比较

在这里插入图片描述
在这里插入图片描述

  • 20
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值