运算符重载

重载运算符的限制
不能重载的算符:
. :: .* ?: sizeof

可以重载的运算符:

      • / % ^ & | ~
        ! = < > += -= = /= %
        ^= &= |= << >> >>= <<= == !=
        <= >= && || ++ – ->
        ‘ ->
        [] () new delete new[] delete[]

重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:

  1. 不改变运算符的优先级
  2. 不改变运算符的结合性
  3. 不改变运算符所需要的操作数
  4. 不能创建新的运算符

运算符函数可以重载为成员函数或友元函数
1.一元运算符
Object op 或 op Object
重载为成员函数,解释为:
Object . operator op ()
操作数由对象Object通过this指针隐含传递
重载为友元函数,解释为:
operator op (Object)
操作数由参数表的参数Object提供

2.二元运算符
ObjectL op ObjectR
重载为成员函数,解释为:
ObjectL . operator op ( ObjectR )
左操作数由ObjectL通过this指针传递,右操作数由参数ObjectR传递
重载为友元函数,解释为:
operator op ( ObjectL, ObjectR )
左右操作数都由参数传递

成员运算符函数的原型在类的内部声明格式如下:

class X {
    //…
返回类型 operator运算符(形参表);
  //…
}

在类外定义成员运算符函数的格式如下:

返回类型 X::operator运算符(形参表)
{
     函数体
}

双目运算符重载为成员函数
对双目运算符而言,成员运算符函数的形参表中仅有一个参数,它作为运算符的右操作数,此时当前对象作为运算符的左操作数,它是通过this指针隐含地传递给函数的。

#include <iostream.h>
class Complex
{
public:
 Complex( ) {real=0,imag=0;}
 Complex(double r,double i) {real=r; imag=i;}
  Complex operator + (Complex &c2); 
 void display( );
  private:
    double real;
    double imag;
};
void Complex::display( ){
 cout<<"("<<real<<","<<imag<<"i)"<<endl;}
Complex Complex:: operator + (Complex &c2) {
 return Complex(real+c2.real, imag+c2.imag);}
int main( ){
 Complex c1(3,4),c2(5,-10),c3;
 c3=c1+c2;//相当于c3=c1.operator +(c2)
 cout<<"c1=";c1.display( );
 cout<<"c2=";c2.display( );
 cout<<"c1+c2 ="; c3.display( );
 return 0;
}

单目运算符重载为成员函数
对单目运算符而言,成员运算符函数的参数表中没有参数,此时当前对象作为运算符的一个操作数。

有一个Time类,包含数据成员minute(分)和sec(秒),模拟秒表,每次走一秒,满60秒进一分钟,此时秒又从0开始算。要求输出分和秒的值。

class Time
{
public:
  Time( ){minute=0;sec=0;}
  Time(int m,int s):minute(m),sec(s){ }
  Time operator++( );     //声明前置自增运算符“++”重载函数
  Time operator++(int);   //声明后置自增运算符“++”重载函数
private:
  int minute;
  int sec;
};
Time Time∷operator++( )    //定义前置自增运算符“++”重载函数
{
 if(sec++>=60) { 
  sec-=60;         //满60秒进1分钟
  minute ++;
 }
 return *this;          //返回当前对象值
}
Time Time∷operator++(int)  //定义后置自增运算符“++”重载函数
{
 Time temp(*this);
 sec++;
 if(sec>=60) {
  sec-=60;
  ++minute;
 }
 return temp;         //返回的是自加前的对象
}

一般而言,采用成员函数重载单目运算符时,以下两种方法是等价的:

    @aa;                // 隐式调用
    aa.operator@();    // 显式调用

成员运算符函数operator @所需的一个操作数由对象aa通过this指针隐含地传递。因此,在它的参数表中没有参数。

用友元函数重载
友元函数重载运算符常用于运算符的左右操作数类型不同的情况

例如:

 class   Complex
{     int    Real ; 
      int    Imag ;
   public :
       Complex ( int a ) { Real = a ;   Imag = 0 ; }     
       Complex ( int  a  , int  b ) { Real = a ;   Imag = b ; }
       Complex  operator + ( Complex ) ;...
} ;   
int   f ( )
{ Complex  z ( 2 , 3 ) ,   k ( 3 , 4 ) ;
   z = z + 27 ;  //z . operator + ( 27 ) OK
   z = 27 + z ;  //27 . operator + ( Z ) NO...
}

在第一个参数需要隐式转换的情形下,使用友元函数重载运算符是正确的选择
友元函数没有 this 指针,所需操作数都必须在参数表显式声明,很容易实现类型的隐式转换
C++中不能用友元函数重载的运算符有:
= () [] ->

#include<iostream>
using namespace std;
class Complex
{ public:
      Complex( double r =0, double i =0 ) { Real = r ;   Image = i ; }
      Complex(int a) { Real = a ;  Image = 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, Image ;
};
  Complex operator + ( const Complex & c1, const Complex & c2 )
  { double r = c1.Real + c2.Real ;  double i = c1.Image+c2.Image ;
     return Complex ( r,  i ) ;
  }
Complex operator - ( const Complex & c1, const Complex & c2 )
  { double r = c1.Real - c2.Real ;  double i = c1.Image - c2.Image ;
     return Complex ( r,  i ) ;
  }
Complex operator- ( const Complex & c )
  { return Complex ( -c.Real, - c.Image ) ; }
void Complex :: print() const
  { cout << '(' << Real << " , " << Image << ')' << endl ; }

成员运算符函数与友元运算符函数的比较:
(1) 成员运算符函数比友元运算符函数少带一个参数(后置的++、–需要增加一个形参)。
(2) 双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但当操作数类型不相同时,必须使用友元函数。

运算符 [] 和 () 是二元运算符
[] 和 () 只能用成员函数重载,不能用友元函数重载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值