运算符重载与C++标准库STL学习总结

一、  运算符重载

运算符重载使得用户自定义的数据以一种更简洁的方式工作。

(一)运算符重载的规则

1.重载运算符的限制

不能重载的算符             

.      ::     .*    ?:    sizeof

可以重载的运算符

+     -      *     /     %    ^     &    |     ~

!      =     <     >     +=   -=    *=   /=   %

^=   &=  |=   <<   >>   >>= <<= ==   !=

<=   >=   && ||   ++   --     ->*  ‘      ->

[]     ()     new       delete   new[]     delete[]

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

  Ø不改变运算符的优先级

  Ø不改变运算符的结合性

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

Ø不能创建新的运算符

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

 Ø 运算符函数可以重载为成员函数或友元函数

1.一元运算符

Object op        op Object

Ø 重载为成员函数,解释为:

Object . operatorop ()

               操作数由对象Object通过this指针隐含传递

  Ø重载为友元函数,解释为:

operator op (Object)

          操作数由参数表的参数Object提供

2. 二元运算符

ObjectL  opObjectR

 Ø 重载为成员函数,解释为:

            ObjectL . operatorop ( ObjectR )

        左操作数由ObjectL通过this指针传递,右操作数由参数ObjectR传递

 Ø重载为友元函数,解释为:

            operator op (ObjectL, ObjectR )

         左右操作数都由参数传递

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

class X {

                 //…

返回类型operator运算符(形参表);

                //…

}

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

返回类型X::operator运算符(形参表)

{

                   函数体

}

5.双目运算符重载为成员函数

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

  一般而言,如果在类X中采用成员函数重载双目运算符@,成员运算符函数operator@ 所需的一个操作数由对象aa通过this指针隐含地传递,它的另一个操作数bb在参数表中显示,aabb是类X的两个对象,则以下两种函数调用方法是等价的:

    aa @ bb;                      // 隐式调用

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

6. 单目运算符重载为成员函数

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

【例】

有一个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指针隐含地传递。因此,在它的参数表中没有参数。

7.用友元函数重载

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

【例】

 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 ;				
      …...
}

 Ø 在第一个参数需要隐式转换的情形下,使用友元函数重载

    运算符是正确的选择

Ø   友元函数没有 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 ; }

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

(1) 成员运算符函数比友元运算符函数少带一个参数(后置的++--需要增加一个形参)。

(2)  双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但当操作数类型不相同时,必须使用友元函数。

(三)几个典型运算符重载

1.数学类中常用的几个运算符重载的特点和应用:

   A  Aobject

运算符 ++ - - 有两种方式:

前置方式:      ++Aobject    --Aobject

成员函数  重载      A :: A operator++ () ;      

       解释为:     Aobject . operator ++( ) ;

    友元函数  重载      friend A operator++ (A &) ;

       解释为:    operator ++( Aobject ) ;

后置方式:       Aobject ++ Aobject –

成员函数  重载      A :: A operator++ (int) ;

       解释为:    Aobject . operator ++( 0 ) ;——伪参数

    友元函数  重载:  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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值