c++中的操作符重载

xiaoxiao2021-02-28  169

  来讲讲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指针,所以可以少一个操作数,而全局函数没有,所以需要两个操作数。

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

转载请注明原文地址: https://www.6miu.com/read-51616.html

最新回复(0)