目录

操作符重载

!!!本文基于这个一个 complex的类去讲解 操作符重载

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class complex {
public:
  complex(double r = 0, double i = 0) : re(r), im(i) {}
  complex& operator+=(const complex&);
  double real() const { return re; }
  double imag() const { return im; }

private:
  double re, im;

  friend complex& __doapl(complex *, const complex &);
};

操作符重载

  1. 示例操作符重载 “+=”

    • +=就是一个操作符,那么操作符是怎么被编译器看待的

    • 下述代码 += 会用到左边的c2上,如果c2有对+=的定义,就会调用+=的函数,操作符本来也就是一个函数

      1
      
      c2 += c1;
      
    • 我们来示范一下重载 += 这个代码就是重写了+=函数,多包装了一层

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      inline complex& __doapl(complex* ths, const complex& r) {
        ths->re += r.re;
        ths->im += r.im;
        return *ths; // 返回的是一个value
      }
      
      inline complex& complex::operator+=(const complex& r) {
        return __doapl(this, r);
      }
      

成员函数 - this

  1. 我们将上面的代码更深一层看,其实是这样的

    • 这个this就是操作符左边的-也就是c2,但是在我们代码里面不可以写出来,知道他的存在就好 那么this就一定在第一个参数吗? 其实不一定的,但是不用考虑

      1
      2
      3
      
      inline complex& complex::operator+=(this, const complex& r) {
        return __doapl(this, r);
      }
      

Return by reference

  1. 还是上面的代码 我们来分析分析一个问题

    • *为什么 complex *ths 是指针的方式传进来的,return 的时候 ths 是返回指针所指向的value,然而声明返回值的时候,说返回的是一个内存地址&

      1
      2
      3
      4
      
      inline complex& __doapl(complex* ths, const complex& r) {
        //  ...
        return *ths;
      }
      
    • 这其实是允许的,你返回一个value,接收端怎么接收,是不需要管的,所以 传递者无需知道接收者是以reference形式接收

非成员函数

  1. 一个操作符也可以有很多个重载

    • 下面三个操作符 + 由复数和实数组成三种,所以需要有三种全局函数

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      {
        complex c1(2, 1);
        complex c2;
      
        c2 = c1 + c2;
        c2 = c1 + 5;
        c2 = 7 + c1;
      }
      
      inline complex operator + (const complex& x, const complex& y) {
        return complex (real(x) + real(y), imag(x) + imag(y));
      }
      
      inline complex operator + (const complex& x, double y) {
        return complex (real(x) + y, imag(x);
      }
      
      inline complex operator + (double x, const complex& y) {
        return complex (x + real(y), imag(y));
      }
      

临时对象

  1. 我们来看看上面 三个 +重载,他们绝不可return by reference
    • 上述的 + 并非等同于 +=xy相加后的数据并没有地方放,所以在函数里一定会放在一个东西里 这里就是complex()
    • conplex()相当于int()都会创建一个临时对象,这样的意思就是这个临时对象下一行就挂了,只是临时的作用

总结

  1. const需不需要使用取决于这个值需不需要修改
  2. pass by reference & return by reference
    • 一切都优先考虑 reference,如果像需要用到临时对象,则使用return by value
    • 同时也要注意 需不需要加上const