运算符重载

原文地址:http://see.xidian.edu.cn/cpp/biancheng/view/217.html

一、什么是运算符重载

所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新功能。运算符也可以重载。实际上,我们已经在不知不觉之中使用了运算符重载。


现在要讨论的问题是: 用户能否根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。譬如,能否用“+”号进行两个复数的相加。在C++中不能在程序中直接用运算符“+”对复数进行相加运算。用户必须自己设法实现复数相加。例如用户可以通过定义一个专门的函数来实现复数相加。见例10.1。

例10.1 通过函数来实现复数相加。
#include <iostream>
using namespace std;
class Complex //定义Complex类
{
   public:
   Complex( ){real=0;imag=0;}    //定义构造函数
   Complex(double r,double i){real=r;imag=i;}  //构造函数重载
   Complex complex_add(Complex &c2);  //声明复数相加函数
   void display( );  //声明输出函数
   private:
   double real;  //实部
   double imag;  //虚部
};

Complex Complex∷complex_add(Complex &c2)
{
   Complex c;
   c.real=real+c2.real;
   c.imag=imag+c2.imag;
   return c;
}

void Complex∷display( ) //定义输出函数
{
   cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;
}
int main( )
{
   Complex c1(3,4),c2(5,-10),c3;//定义3个复数对象
   c3=c1.complex_add(c2); //调用复数相加函数
   cout<<″c1=″; c1.display( );//输出c1的值
   cout<<″c2=″; c2.display( );//输出c2的值
   cout<<″c1+c2=″; c3.display( );//输出c3的值
   return 0;
}
运行结果如下:
c1=(3+4i)
c2=(5-10i)
c1+c2=(8,-6i)

结果无疑是正确的,但调用方式不直观、太烦琐,使人感到很不方便。能否也和整数的加法运算一样,直接用加号“+”来实现复数运算呢?如
   c3=c1+c2;
编译系统就会自动完成c1和c2两个复数相加的运算。如果能做到,就为对象的运算提供了很大的方便。这就需要对运算符“+”进行重载。

运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。

重载运算符的函数一般格式如下:
函数类型 operator 运算符名称 (形参表列)
{ 对运算符的重载处理 }


例如,想将“+”用于Complex类(复数)的加法运算,函数的原型可以是这样的:

   Complex operator+ (Complex& c1,Complex& c2);


二、运算符重载方法

在定义了重载运算符的函数后,可以说: 函数operator+重载了运算符+。
为了说明在运算符重载后,执行表达式就是调用函数的过程,可以把两个整数相加也想像为调用下面的函数:
int operator + (int a,int b)
{return (a+b);}

如果有表达式5+8,就调用此函数,将5和8作为调用函数时的实参,函数的返回值为13。这就是用函数的方法理解运算符。可以在例10.1程序的基础上重载运算符“+”,使之用于复数相加。

例10.2 改写例10.1,重载运算符“+”,使之能用于两个复数相加。
#include <iostream>
using namespace std;
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;
};
Complex Complex∷operator+(Complex &c2) //定义重载运算符的函数
{
   Complex c;
   c.real=real+c2.real;//这一步中的real就是this->real,默认是调用这个函数的对象的real
   c.imag=imag+c2.imag;
return c;
}

void Complex∷display( )
{
   cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;
}

int main( )
{
   Complex c1(3,4),c2(5,-10),c3;
   c3=c1+c2; //运算符+用于复数运算  对应的就是c1
   cout<<″c1=″;c1.display( );
   cout<<″c2=″;c2.display( );
   cout<<″c1+c2=″;c3.display( );
   return 0;
}
运行结果与例10.1相同:
c1=(3+4i)
c2=(5-10i)
c1+c2=(8,-6i)

请比较例10.1和例10.2,只有两处不同:

  1. 在例10.2中以operator+函数取代了例10.1中的complex_add函数,而且只是函数名不同,函数体和函数返回值的类型都是相同的。
  2. 在main函数中,以“c3=c1+c2;”取代了例10.1中的“c3=c1.complex_add(c2);”。在将运算符+重载为类的成员函数后,C++编译系统将程序中的表达式c1+c2解释为
       c1.operator+(c2)  //其中c1和c2是Complex类的对象
    即以c2为实参调用c1的运算符重载函数operator+(Complex &c2),进行求值,得到两个复数之和。

虽然重载运算符所实现的功能完全可以用函数实现,但是使用运算符重载能使用户程序易于编写、阅读和维护。在实际工作中,类的声明和类的使用往往是分离的。假如在声明Complex类时,对运算符+,-,*,/都进行了重载,那么使用这个类的用户在编程时可以完全不考虑函数是怎么实现的,放心大胆地直接使用+,-,*,/进行复数的运算即可,十分方便。
对上面的运算符重载函数operator+还可以改写得更简练一些:
Complex Complex∷operator + (Complex &c2)
{return Complex(real+c2.real, imag+c2.imag);}

需要说明的是: 运算符被重载后,其原有的功能仍然保留,没有丧失或改变。通过运算符重载,扩大了C++已有运算符的作用范围,使之能用于类对象。

运算符重载对C++有重要的意义,把运算符重载和类结合起来,可以在C++程序中定义出很有实用意义而使用方便的新的数据类型。运算符重载使C++具有更强大的功能、更好的可扩充性和适应性,这是C++最吸引人的特点之一。
  1. C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。
  2. C++允许重载的运算符。

C++中绝大部分的运算符允许重载,不能重载的运算符只有5个:
.  (成员访问运算符)
.* (成员指针访问运算符)
∷ (域运算符)
sizeof(长度运算符)

?: (条件运算符)


如前面例10.2程序中对运算符“+”进行了重载,使之能用于两个复数的相加。在该例中运算符重载函数operator+作为Complex类中的成员函数。“+”是双目运算符,为什么在例10.2程序中的重载函数中只有一个参数呢?实际上,运算符重载函数有两个参数,由于重载函数是Complex类中的成员函数,有一个参数是隐含的,运算符函数是用this指针隐式地访问类对象的成员。

可以看到,重载函数operator+访问了两个对象中的成员,一个是this指针指向的对象中的成员,一个是形参对象中的成员。如this->real+c2.real,this->real就是c1.real。上节中已说明,在将运算符函数重载为成员函数后,如果出现含该运算符的表达式,如c1+c2,编译系统把它解释为
   c1.operator+(c2)
即通过对象c1调用运算符重载函数,并以表达式中第二个参数(运算符右侧的类对象c2)作为函数实参。运算符重载函数的返回值是Complex类型,返回值是复数c1和c2之和(Complex(c1.real + c2.real,c1.imag+c2.imag))。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值