运算符重载

Posted ZYVV

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运算符重载相关的知识,希望对你有一定的参考价值。

1.运算符重载规则

     在c++中,操作符和函数时等价的,统一的。因此,运算符也可以重载,虽然系统已经预定了一些操作符的功能,但毕竟应用有所限制,不能灵活得解决各种问题,而运算符重载可以赋予已有的运算符多重含义。通过重新定义运算符,使它能够用于特定类的对象执行特定的功能,使得c++具有很强的可拓展性。

c++中可重载运算符有一下几种:

算术运算符:+,-,*,/,%,++,--;

位操作运算符:&,|,~,^,<<,>>

逻辑运算符:!,&&,||;

比较运算符:<,>,>=,<=,==,!=;

赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;

其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。

有五个不可重载运算符:

.          成员运算符
.*         指向成员的指针
::         作用域运算符
?:         条件运算符
sizeof     类型长度运算符

2.以成员函数形式重载运算符

成员函数形式的运算符声明与成员函数类似,首先应当类定义中声明该运算符,声明的具体形式如下所示:

返回类型    operator 运算符(参数列表)

既可以在类定义的同时定义运算符函数使其成为inline函数,也可以在类定义之外定义运算符函数,但是要使用作用域限定符“::”,类外定义的基本格式如下所示:
返回类型    类名::operator    运算符(参数列表)

以下代码定义了复数类,并重载了其四则运算。

  1 /***********************complex.h******************/
  2 #include <iostream.h>
  3 using  namespace std;
  4 class  complex
  5 {
  6     private:
  7          double real,imag;
  8     public:
  9          complex(double r = 0.0,double i = 0.0)
 10          {
 11               real =  r;
 12               imag = i;
 13          }
 14          complex  operator + (const  complex &);
 15          complex  operator - (const  complex &);
 16          complex  operator -  ();                             //取反运算符
 17          complex  operator * (const  complex &);
 18          complex  operator / (const  complex &);
 19          complex  operator ++ ();                             //前置++
 20          complex  operator ++ (int) ;                         //后置++
 21          void  disp()
 22          {
 23               cout<<real<<"  +  "<<"i*"<<imag<<endl;
 24          }
 25 };
 26 
 27 /*******************complex.cpp*****************/
 28 #include "complex.h"
 29 complex complex::operator + (const  complex&  CC)
 30 {
 31     return  complex(real + CC.real,imag + CC.imag);
 32 }
 33 
 34 complex complex::operator - (const  complex&  CC)
 35 {
 36     return  complex(real - CC.real,imag - CC.imag);
 37 }
 38 
 39 complex complex::operator - ()
 40 {
 41     return  complex(-real ,-imag;
 42 }
 43 
 44 complex complex::operator * (const  complex&  CC)
 45 {
 46     return  complex(real*CC.real - imag*CC.imag , real*CC.imag + imag*CC.real);
 47 }
 48 
 49 complex complex::operator / (const  complex&  CC)
 50 {
 51     return  complex((real*CC.real + imag + CC.imag)/(CC.real*CC.real + CC.imag*CC.imag),(imag*CC.real - real*CC.imag)/(CC.real*CC.real + CC.imag*C.imag));
 52 }
 53 
 54 complex&   complex::operator  ++()
 55 {
 56     cout<<"前置++"<<endl;
 57     real +=1;
 58     imag +=1;
 59     returun (*this);
 60 }
 61 
 62 complex&   complex::operator  ++(int)
 63 {
 64     cout<<"后置++"<<endl;
 65     complex ctemp = *this;
 66     ++(*this);
 67     return  ctemp;
 68 }
 69 
 70 
 71 /*********************main.c*****************/
 72 #include "complex.h"
 73 int main()
 74 {
 75      complex cx1(1.0,2.0),cx2(3.0,4.0),cxRes;
 76      cxRes = cx1 - cx2;
 77      cxRes.disp();
 78 
 79      cxRes = -cx1;
 80      cxRes.disp();
 81 
 82      cxRes = cx1 + cx2;
 83      cxRes.disp();
 84 
 85      cxRes = cx1 * cx2;
 86      cxRes.disp();
 87 
 88      cxRes = cx1 / cx2;
 89      cxRes.disp();
 90 
 91      complex cx3(1.0,1.0),cx4(5.0,5.0);
 92      cxRes = ++cx3;
 93      cxRes.disp();
 94      cx3.disp();
 95 
 96      cxRes = cx4++;
 97      cxRes.disp();
 98      cx4.disp();
 99 
100     return 0;
101 }

输出结果为:

 1 -2  +  i*-2
 2 -1  +  i*-2
 3 4   +  i*6
 4 -5  +  i*10
 5 0.36  +  i*0.08
 6 前置++
 7 2  +  i*2
 8 2  +  i*2
 9 后置++
10 前置++
11 5  +  i*5
12 6  +  i*6

3.以友元函数形式重载运算符

用成员函数重载双目运算符时,左操作数无需参数输入,而是通过隐含的this指针传入,这种做法效率比较高。此外,操作符还可以重载为友元函数形式,这样没有隐含的参数this指针。对双目运算符,友元函数有两个参数,对单目运算符,友元函数有一个参数,声明格式如下:

friend   返回类型  operator   运算符(参数表)

4.友元函数形式和成员函数形式的比较

对于绝大多数可重载操作符,两种重载形式都是允许的,但是对于下述运算符,只能使用成员函数形式:

[]    下标运算符
=     赋值运算符
()    函数调用运算符
->    用指针访问对象成员

错误使用例子:

用两种形式编译如下代码:

complex  c1(1.0,2.0),cRes;
cRes = 5 + c1;

使用成员函数形式会报错,因为编译器将它解释为

cRes = 5.operator + (c1);

而友元函数形式解释为

cRes = operator +(5,c1);
这时编译器会根据合适的构造函数将“5”转换为complex临时变量,完成参数匹配,实现加法操作。

 

以上是关于运算符重载的主要内容,如果未能解决你的问题,请参考以下文章

C++提高:运算符重载

导航架构片段重载问题

导航架构片段重载问题

Javascript实现运算符重载

GroovyGroovy 运算符重载 ( 运算符重载 | 运算符重载对应方法 )

运算符 + 重载 C++