重载运算符总结

重载运算符

1.不能重载的5个运算符

.   .*   ::   ?:  sizeof

2重载运算符的限制

①不改变运算符的优先级

②不改变运算符的结合性

③不改变运算符所需要的操作数

3.运算符重载是一种特殊的成员函数或友元函数

   成员函数语句格式

       类型 类名::operator op(参数表){   }

   类型指函数的返回类型 类名是要重载该运算符的类 op是要重载的运算符 函数名是operator op 参数表列出该运算符所需要的    操作数

4.一元运算符(一个操作数)

Objectop或op Object

(1)当重载为成员函数时,编译器解释为Object operator op()

函数operator op所需的操作数由对象Object通过this指针隐含传递,所以参数表为空

(2)重载为友元函数,解释为operator op (Object)

函数operator op所需的操作数由参数表的参数Object提供

5.二元运算符(两个操作数)

二元运算符要求有左右两个操作数ObjectL  op ObjectR

(1)重载为成员函数,解释为ObjectL . operator op (ObjectR )

    左操作数由对象ObjectL通过this指针传递,右操作数由参数ObjectR传递(一般用传引用&)

(2)重载为友元函数,解释为operator op ( ObjectL,ObjectR )

      左右操作数都由参数传递

 注:用成员函数或友元函数重载关键区别 成员函数有this指针 友元函数没有this指针

6.用成员函数重载运算符

当一元运算符的操作数,或二元运算符的操作数是该类的一个对象时,重载运算符一般定义为成员函数

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

class X {
    //…
返回类型 operator运算符(形参表);
  //…
}
在类外定义成员运算符函数的格式如下:
返回类型 X::operator运算符(形参表)
{
     函数体
}
注:对双目运算符而言,成员运算符函数的形参表中仅有一个参数,它作为运算符的右操作数,此时当前对象作为运算符的左操作数,它是通过 this指针 隐含地传递给函数的。
对单目运算符而言,成员运算符函数的参数表中 没有参数, 此时当前对象作为运算符的一个操作数。

例:
有一个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;         //返回的是自加前的对象
}
7.友元重载
友元函数重载运算符常用于运算符的左右操作数类型不同的情况
(1) 在第一个参数需要隐式转换的情形下,使用友元函数重载 运算符是正确的选择
(2) 友元函数没有 this 指针,所需操作数都必须在参数表显式 声明,很容易实现类型的隐式转换
(3) 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)  双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但当操作数类型不相同时,必须使用友元函数。
 

8.典型运算符重载


(1)++与--

  • 前置方式: ++Aobject --Aobject

  成员函数重载 A :: A operator++ () ;
解释为: Aobject . operator ++( ) ;
    友元函数重载 friend A operator++ (A &) ;
解释为: operator ++( Aobject ) ;
  • 后置方式: Aobject++ Aobject --
  成员函数重载 A :: A  operator++ (int) ;
解释为: Aobject . operator ++( 0 ) ; 前+参数表为空 后+operator++(int))
    友元函数重载: friend A operator++ (A &, int) ;
解释为: operator++(Aobject, 0)
例:成员函数重载++


#include<iostream>
using namespace std;
class  Increase
{ public :
     Increase ( ) { value=0; }
     void  display( )  const { cout<<value<<'\n'; } ;
     Increase  operator ++ ( ) ; 	     // 前置
     Increase  operator ++ ( int ) ; 	     // 后置
  private:   unsigned  value ;
};
Increase  Increase :: operator ++ ( ) 	
  { value ++ ;   return *this ; }	
Increase  Increase :: operator ++ ( int )	
 { Increase  temp;   temp.value = value ++ ;   return  temp; }
int main( )
  { Increase   a ,  b , n ;    int  i ;
     for ( i = 0 ; i < 10 ; i ++ )  a = n ++ ;
     cout <<"n= " ;  n.display( ) ;   cout <<"a= " ;   a.display( ) ;
     for ( i = 0 ; i < 10 ; i ++ )  b = ++ n ;
     cout << "n= " ;   n.display( ) ;   cout << "b= " ;   b.display( ) ;
 }

友元重载++

#include<iostream>
using namespace std;
class  Increase
{ public :
     Increase ( ) { value=0; }
     void  display( )  const { cout<<value<<'\n'; } ;
     friend Increase  operator ++ ( Increase & ) ; 	 // 前置	
     friend Increase  operator ++ ( Increase &, int ) ;	 // 后置
  private:   unsigned  value ;
};
Increase  operator ++ ( Increase & a )
  { a.value ++ ;   return a ; }	
Increase  operator ++ ( Increase & a, int )
 { Increase  temp(a);   a.value ++ ;   return  temp; }
int main( )
  { Increase   a ,  b , n ;    int  i ;
     for ( i = 0 ; i < 10 ; i ++ )  a = n ++ ;
     cout <<"n= " ;  n.display( ) ;   cout <<"a= " ;   a.display( ) ;
     for ( i = 0 ; i < 10 ; i ++ )  b = ++ n ;
     cout << "n= " ;   n.display( ) ;   cout << "b= " ;   b.display( ) ;
 }

(2)重载赋值运算符=

赋值运算符重载用于对象数据的复制
 operator= 必须重载为 成员函数
重载函数原型为:
类名  &  类名  :: operator= ( 类名 ) ;

(3)重载运算符[]和()

运算符 [] 和 () 是二元运算符
[] 和 () 只能用成员函数 重载,不能用友元函数重载
  • []运算符用于访问数据对象的元素
重载格式 类型  类 :: operator[]  ( 类型 ) ;
例如,类X有重载函数:int & X::operator[](int);     求第几个数

其中,x是X类的对象,则调用函数的表达式:x[k]      被解释为:x.operator[](K)

  • ()运算符用于函数调用
    重载格式 类型  类 :: operator()  ( 参数表  ) ;
    设 x 是类 X 的一个对象,则表达式
    x ( arg1, arg2, … )
    可被解释为
    x . operator () (arg1, arg2, … )

(4)重载<<和>>(只能重载为友元函数)


运算符 << 由ostream 重载为插入操作,用于输出基本类型数据
运算符 >> 由 istream 重载为提取操作,用于输入基本类型数据
用友元函数重载 << 和 >> ,输出和输入用户自定义的数据类型
  • 重载输出运算符“<<”(只能被重载成友元函数,不能重载成成员函数)
       定义输出运算符 << 重载函数的一般格式如下 :
    ostream& operator<<(ostream& out,class_name& obj)
    {
          out<<obj.item1;
          out<<obj.item2;
          .. .
          out<<obj.itemn;
          return out;
    }//全输出

  • 重载输入运算符“>>” (只能被重载成友元函数)
          定义输入运算符函数 >> 重载函数的一般格式如下 :
    istream& operator>>(istream& in,class_name& obj)
    {
            in>>obj.item1;
            in>>obj.item2;
            . . .
            in>>obj.itemn;
            return in;
    }
例:
#include<iostream>
#include<cstdlib>
using namespace std;
class vector
{ public :
     vector( int size =1 ) ;       ~vector() ;
     int & operator[] ( int i ) ;
     friend ostream & operator << ( ostream & output , vector & ) ;
     friend istream & operator >> ( istream & input, vector & ) ;
  private :  
     int * v ;     int len ;
};
int main(){
   int k ;    cout << "Input the length of vector A :\n" ;     cin >> k ;
  vector A( k ) ;    cout << "Input the elements of vector A :\n" ;    
   cin >> A ;          cout << "Output the elements of vector A :\n" ;
  cout << A ;
}
vector::vector( int size ) 
{ if (size <= 0 || size > 100 )
    { cout << "The size of " << size << " is null !\n" ; exit( 0 ) ;  }
   v = new int[ size ] ;  len = size ;
}
vector :: ~vector() { delete[] v ;  len = 0 ; }
int & vector :: operator [] ( int i ) 		
{ if( i >=0 && i < len )  return v[ i ] ;
  cout << "The subscript " << i << " is outside !\n" ;  exit( 0 ) ;
}
ostream & operator << ( ostream & output, vector & ary )
{ for(int i = 0 ; i < ary.len ; i ++ )  output << ary[ i ] << "  " ;
   output << endl ;
   return output ;
}
istream & operator >> ( istream & input, vector & ary )	
{ for( int i = 0 ; i < ary.len ; i ++ )  input >> ary[ i ] ;
   return  input ;
}

9.心得体会

    使用重载运算符后,程序更加直观简洁,能够自己定义需要的操作类型,但是在写ATM程序中想要尝试使用重载运算符,不知道如何下手,不知道应该改哪些部分,对着课本现有的程序改了一小部分,但是有的地方没有调通,对于重载运算符的使用规则和用法还是有很多疑问。主要存在的问题有使用成员函数和友元函数的用法区别,应该注意哪些情况使用友元 哪些使用成员函数,语法规则如何。在判断时间时用重载运算符<简化代码,更加直观,一个数据对象整体输入整体输出 用<< 全输入,用>>全输出。在调好一个程序后,可以尝试着使用重载运算符简化程序,使程序功能更加清晰明了,多加练习,逐渐熟悉重载的使用语法形式,尤其是重载<和<<与>>,当然前提是要掌握成员函数与友元函数的使用语法规则。现在还没有体会到重载运算符的突出之处,尝试在程序中使用一些重载,慢慢领悟它的独到之处。


猜你喜欢

转载自blog.csdn.net/fsy20171796/article/details/80457060
今日推荐