c++中的操作符重载

来源:互联网 发布:autodesk 软件绘图技巧 编辑:程序博客网 时间:2024/06/15 12:52

  来讲讲c++强大特性之一,操作符重载。
  中学时的数学课程学习的复数,其形式为:a + bi(a、b均为实数),其中a称为实部,b称为虚部,i称为虚数单位。复数和实数一样,可以进行加减乘除等运算。那么我们可以构建一个复数类,如下。

class ComplexNumber{public:    int a;  //实部    int b;  //虚部        };

  根据复数运算规则,两个复数可以相加,其运算规则为实部加实部,虚部加虚部,那么下面代码可行?

class ComplexNumber{public:    int a;  //实部    int b;  //虚部        ComplexNumber(int a, int b)    {        this->a = a;        this->b = b;    }   };int main(void){    ComplexNumber c1(1, 2);    ComplexNumber c2(5, 9);    ComplexNumber c3 = c1 + c2;    printf("c3.a = %d, c3.b = %d\n", c3.a, c3.b);    return 0;}

编译自然报错:
这里写图片描述

加法操作符只能针对于实数之间,怎么可以用于对象之间。
为实现复数相加功能,我们可以定义一个成员函数Add(),专门实现此功能:

class ComplexNumber{private:    int a;  //实部    int b;  //虚部    public:    ComplexNumber(int a, int b)    {        this->a = a;        this->b = b;    }    ComplexNumber Add(ComplexNumber& c1, ComplexNumber& c2)    {        ComplexNumber ret(c1.a + c2.a, c1.b + c2.b);        return (ret);    }    int getA()    {        return a;       }    int getB()    {        return b;    }};int main(void){    ComplexNumber c1(1, 2);    ComplexNumber c2(5, 9);    //ComplexNumber c3 = c1 + c2;    ComplexNumber c3 = c1.Add(c1, c2);    printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());    return 0;}

考虑到数据的封装性,可以将成员变量a和b设置为private属性。
编译运行正常:
这里写图片描述

  在c++中,通过对象调用成员函数时,不要忘记还有this指针这一说(this指针可以看文章http://blog.csdn.net/qq_29344757/article/details/76427588),this指针会指向对象的自身,所以对于Add()成员函数,我们可以只传递一个ComplexNumber对象即可:

class ComplexNumber{    //...    ComplexNumber Add(ComplexNumber& c)  //this指针会传来一个ComplexNumber对象,作为加数之一    {        ComplexNumber ret(this->a + c.a, this->b + c.b);        return (ret);    }    //...};int main(void){    //...    ComplexNumber c3 = c1.Add(c2);    printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());}

其运行结果和前面一样。

  成员函数Add()实现了两个复数对象的相加问题,但是c++中操作符重载特性的存在,可以让“+”支持两个复数相加,也就是让两个自定义的类类型相加。如何实现?

先看操作符重载的基本语法:

Type operator sym(const Type& c1, const Type& c2){    Type ret;    //...    return ret;}

  注意,operator为关键字,sym为已定义的操作符,如+,-,*,/,%,>>等等。
  通过operator定义的函数,可以为已定义的操作符拥有新的操作。稍微修改下前面的Add()函数即可:

class ComplexNumber{private:    int a;  //实部    int b;  //虚部    public:    ComplexNumber(int a, int b)    {        this->a = a;        this->b = b;    }    ComplexNumber operator+ (ComplexNumber& c)    {        ComplexNumber ret(this->a + c.a, this->b + c.b);        return (ret);    }    int getA()    {        return a;       }    int getB()    {        return b;    }};int main(void){    ComplexNumber c1(1, 2);    ComplexNumber c2(5, 9);    ComplexNumber c3 = c1.operator+(c2);    //调用c1的operator+()成员函数    //ComplexNumber c3 = c1.Add(c2);    printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());    return 0;}

编译运行:
这里写图片描述

这样对operator+()函数调用跟调用Add()没啥两样区别,那要是这样呢?

ComplexNumber c3 = c1 + c2;

  这样岂不是实现了两个对象直接调用“+”执行相加操作了么。c++操作符重载的强大之处在于,直接通过“+”符号,编译器会自动检索到operatorr+()函数,且能够正确匹配“+”两边的操作数。

  c++中函数重载的意义就在于扩展函数的功能,使得相同的函数名可以有其它功能,调用的时候,根据上下文(实质就是根据函数参数)调用对应的功能的函数。

  操作符重载也是类似的概念,其本质是通过函数来扩展操作符的功能,这个函数是以operator关键字加上操作符来声明定义的,如上的ComplexNumber operator+ (ComplexNumber& c)。在使用已被重载的操作符来实现对应操作时,如使用“+”实现加法操作,程序如何知道是要使用操作符的重载函数呢?也是根据上下文决定的,这个特性跟前面函数重载根据函数参数调用相对应功能函数一样。另外,全局函数和成员函数都可以实现对操作符的重载,它们最为关键的区别在于,类的成员函数,具有this指针,所以可以少一个操作数,而全局函数没有,所以需要两个操作数。

  复数类的操作不仅仅有+,还有-,*,/,=,==和!=等,依照这个例子就不难实现了。