page contents

C++运算符重载的概念和语法

所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能。

所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能。

实际上,我们已经在不知不觉中使用了运算符重载。例如,+号可以对不同类型(int、float 等)的数据进行加法操作;<<既是位移运算符,又可以配合 cout 向控制台输出数据。C++ 本身已经对这些运算符进行了重载。

C++ 也允许程序员自己重载运算符,这给我们带来了很大的便利。

下面的代码定义了一个复数类,通过运算符重载,可以用+号实现复数的加法运算:



  1. #include <iostream>

  2. using namespace std;

  3. classcomplex{

  4. public:

  5. complex();

  6. complex(double real, double imag);

  7. public:

  8. //声明运算符重载

  9. complexoperator+(const complex&A) const;

  10. void display() const;

  11. private:

  12. double m_real;  //实部

  13. double m_imag;  //虚部

  14. };

  15. complex::complex(): m_real(0.0), m_imag(0.0){ }

  16. complex::complex(double real, double imag): m_real(real), m_imag(imag){ }

  17. //实现运算符重载

  18. complexcomplex::operator+(const complex&A) const{

  19. complexB;

  20. B.m_real = this->m_real + A.m_real;

  21. B.m_imag = this->m_imag + A.m_imag;

  22. return B;

  23. }

  24. void complex::display() const{

  25. cout<<m_real<<" + "<<m_imag<<"i"<<endl;

  26. }

  27. int main(){

  28. complexc1(4.3, 5.8);

  29. complexc2(2.4, 3.7);

  30. complexc3;

  31. c3 = c1 + c2;

  32. c3.display();

  33. return 0;

  34. }

运行结果:
6.7 + 9.5i

本例中义了一个复数类 complex,m_real 表示实部,m_imag 表示虚部,第 10 行声明了运算符重载,第 21 行进行了实现(定义)。认真观察这两行代码,可以发现运算符重载的形式与函数非常类似。

运算符重载其实就是定义一个函数,在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数。也就是说,运算符重载是通过函数实现的,它本质上是函数重载。

运算符重载的格式为:

返回值类型 operator 运算符名称 (形参表列){
    //TODO:
}

operator是关键字,专门用于定义重载运算符的函数。我们可以将operator 运算符名称这一部分看做函数名,对于上面的代码,函数名就是operator+

运算符重载函数除了函数名有特定的格式,其它地方和普通函数并没有区别。

上面的例子中,我们在 complex 类中重载了运算符+,该重载只对 complex 对象有效。当执行c3 = c1 + c2;语句时,编译器检测到+号左边(+号具有左结合性,所以先检测左边)是一个 complex 对象,就会调用成员函数operator+(),也就是转换为下面的形式:

c3 = c1.operator+(c2);

c1 是要调用函数的对象,c2 是函数的实参。

上面的运算符重载还可以有更加简练的定义形式:



  1. complexcomplex::operator+(const complex&A)const{

  2. return complex(this->m_real + A.m_real, this->m_imag + A.m_imag);

  3. }

return 语句中的complex(this->m_real + A.m_real, this->m_imag + A.m_imag)会创建一个临时对象,这个对象没有名称,是一个匿名对象。在创建临时对象过程中调用构造函数,return 语句将该临时对象作为函数返回值。

在全局范围内重载运算符

运算符重载函数不仅可以作为类的成员函数,还可以作为全局函数。更改上面的代码,在全局范围内重载+,实现复数的加法运算:



  1. #include <iostream>

  2. using namespace std;

  3. classcomplex{

  4. public:

  5. complex();

  6. complex(double real, double imag);

  7. public:

  8. void display() const;

  9. //声明为友元函数

  10. friend complexoperator+(const complex&A, const complex&B);

  11. private:

  12. double m_real;

  13. double m_imag;

  14. };

  15. complexoperator+(const complex&A, const complex&B);

  16. complex::complex(): m_real(0.0), m_imag(0.0){ }

  17. complex::complex(double real, double imag): m_real(real), m_imag(imag){ }

  18. void complex::display() const{

  19. cout<<m_real<<" + "<<m_imag<<"i"<<endl;

  20. }

  21. //在全局范围内重载+

  22. complexoperator+(const complex&A, const complex&B){

  23. complexC;

  24. C.m_real = A.m_real + B.m_real;

  25. C.m_imag = A.m_imag + B.m_imag;

  26. return C;

  27. }

  28. int main(){

  29. complexc1(4.3, 5.8);

  30. complexc2(2.4, 3.7);

  31. complexc3;

  32. c3 = c1 + c2;

  33. c3.display();

  34. return 0;

  35. }

运算符重载函数不是 complex 类的成员函数,但是却用到了 complex 类的 private 成员变量,所以必须在 complex 类中将该函数声明为友元函数。

当执行c3 = c1 + c2;语句时,编译器检测到+号两边都是 complex 对象,就会转换为类似下面的函数调用:

c3 = operator+(c1, c2);

小结

虽然运算符重载所实现的功能完全可以用函数替代,但运算符重载使得程序的书写更加人性化,易于阅读。运算符被重载后,原有的功能仍然保留,没有丧失或改变。通过运算符重载,扩大了C++已有运算符的功能,使之能用于对象。

attachments-2021-04-iK7R1IB76088079f7ab6e.jpg

  • 发表于 2021-04-27 20:47
  • 阅读 ( 576 )
  • 分类:C/C++开发

0 条评论

请先 登录 后评论
小柒
小柒

1470 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章