运算符重载学习总结

 

实际上我们在学习这一部分内容时,也一直在运用运算符重载技术,例如,对+运算符,可将两个整型数相加,如1+9,也可将两个实型数相加,如2.5+9.6。这时编译系统在内部重载了两种不同数据类型的加法运算,这种重载的实质是函数重载,即int add(int,int)和float add(float,float)。但是编译系统内定的运算符重载形式,只能对系统定义的基本数据类型起作用,对用户自己定义的数据类型一无法提供相应的运算符重载形式。但我们也可以通过一些操作实现运算符重载。

一. 重载运算符规则

1. 不可以重载的运算符

 .* ::  ?:  sizeof

可以重载的运算符

+ - +      -     *      /      %     ^     &    |      ~

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

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

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

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

2.重载运算符的限制

不改变运算符的优先级

不改变运算符的结合性

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

不能创建新的运算符(运算符重载时一定要注意)

3.运算符重载的语法形式

运算符函数定义的一般格式如下: 
   <返回类型说明符> operator <运算符符号>(<参数表>) 
  {... 
   <函数体> 
  } 

二. 运用成员/友元函数重载运算符

1.    用成员函数重载运算符:

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

class X {

    //…

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

  //…

}

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

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

{

     函数体

}

(1)运算符成员函数只能定义运算符的含义,不能改变运算符的优先级和结合顺序.例如,不论按何种方式重载运算符,a+b*c始终是先乘后加;而a=b=c也要先做b=c,然后,再对a赋值.

(2)运算符重载时,不能改变其目数.例如,任何企图把%定义为单目运算符,或把!定义为双目运算符的做法都会出错.

(3)运算符函数即可在中定义,也可以在类外定义.在类外定义时,它至少应有一个相应类的参数.

(4)无论是在类中定义的运算符成员函数,还是在类外定义的运算符函数,都可以进行重载。也就是说可以定义多个同名的运算符函数。但其参数类型应有差别,否则会产生二义性。

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

下面来看一个双目运算符重载为成员函数的例子


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

对于双目运算符@,当它用作成员函数时,只带一个参数(另一个运算符有调用它的对象给出),此时aa@bb与aa.operator@(bb)等价,当他用作外部函数时,带有两个参数(分别说明两个运算数),此时aa @bb与aa.operator@(aa,bb)等价。如果在类X中采用成员函数重载双目运算符@,成员运算符函数operator@ 所需的一个操作数由对象aa通过this指针隐含地传递,它的另一个操作数bb在参数表中显示,aa和bb是类X的两个对象,则以下两种函数调用方法是等价的:

 

       aa @ bb;                      // 隐式调用

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

 

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

   对于单目前缀运算符@,当它用作成员函数时,不必带参数(运算符就是调用它的对象),此时@aa与aa.operator@()等价,当它用作外部函数时,带有一个参数(分别说明两个运算数),此时@aa与operator@(aa)等价。

1.  用友元函数重载

运算符重载函数是友元函数

  语法形式:

Typeoperator@(参数表)

  {

    //相对于该类而定义的操作

   }

(1)不能用友元函数重载的运算符:

      = 、 ( )、[]、- >

(2)注意:

对THIS所指向的数据的任何改变都会影响到激活运算数函数的对象。

可使用引用参数(指针)来解决重载时的二义性。

(3)在第一个参数需要隐式转换的情形下,使用友元函数重载运算符是正确的选择。

(4)友元函数没有this 指针,所需操作数都必须在参数表显式。

用友元函数重载运算符来实现复数的运算:

#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 ;
};

成员运算符函数与友元运算符函数的区别:

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

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

三.几个典型的运算符重载

一、关于++和- -

1、++和- -的两种形式:

前缀:++i;后缀:i--;

2、 (1)对于前缀方式++i:

    成员函数:XX::operator ++ ();

    友元函数:X operator ++ (X&);

(2)对于后缀方式i++:

  成员函数:XX::operator ++ (int);

    友元函数:X operator ++(X&, int);

    第二个参数INT一般设置为0,如:

 i++  等价于:i++(0)  或:i++=0

实例:

(1)成员函数重载++

Class X
  {
   …
   X operator ++()
	{
	 a++;
	 b++;
	 return *this;
	}
  X operator ++(int x)
	{
	 X temp;
	 a++;
	 b++;
	 return temp;
	}

友元函数重载++:

Class X
  {
   …
   friend operator ++(Y &a)
	{
	 a.x++;
	 b.y++;
	 return a;
	}
  friend operator ++(Y &a, int i)
	{
	 Y temp=a;
	 a.x++;
	 b.y++;
	 return temp;
	}

重载赋值运算符:

赋值运算符重载用于对象数据的复制

 operator= 必须重载为成员函数

重载函数原型为:

       类名  &  类名  :: operator= ( 类名 ) ;

重载运算符()和[]:

一、重载函数调用运算符()

1、函数为:operator();

2、格式:

       X x;

     x(arg1, arg2)  可被解释为:x. operator ()(arg1,arg2);

二、重载下标运算符[];

1、函数为:operator[];

2、格式:

       X x;

     x(y) 可被解释为:x.operator [  ](y);

3、两都者只能采用成员函数重载,不能使用友元函数。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值