• C++ 重载


    操作符就是一种函数,是可以让你重新定义的
    比如说相加,与其自己写个相加函数 plus(u,v); 将u,v相加,
    用 "+" 号 显得更为方便,可读性更高,所以C++就出现了重载运算符这个功能。
    并且可以实现将各种你需要的属性相加。

    一般来说,重载操作符的对象会有接收者和传递者

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


    上面那个this,是不需要写的 比如 complex c1,c2;
    c1 += c2;
    c1就是this。代表操作对象中的接收者。
    所以一般会这么写

    inline complex&
    complex::operator += (const complex& r){ //省略了this
    return __doapl(this,r);
    }

    return by reference语法分析
    传递者无需知道接收者是以什么形式接收

    inline complex& __doapl(complex * ths,const complex& r){
    ...
    return *ths;
    }
    
    inline complex&
    complex::operator += (const complex& r){
    return __doapl(this,r);
    }

    可以看到 第一个函数明明是 complex& __doapl(...)
    返回的却是一个value,return *ths, 这里是没有错误的,因为C++有个特性,就是return by reference,一般来说返回一个引用,会比返回一个值快很多,接收者与其接收其值,不如接收它的引用(也就是地址),而且传递者也不需要知道接收者如何接收,这样下来整个程序会快很多,避免了很多转换。
    complex::operator += (const complex& r) 也是一样,接收的是 c2 的引用,而不需要接收c2的值,直接通过引用去得到它的值,比起创建一个临时空间去转换去获取它的值要快的多。

    temp object(临时对象) typename();
    刚刚说到了return by reference 比传value快,但下面这些情况,是一定不能return by reference的。

    {
    complex c1(2,1);
    complex c2;
    
    c2 = c1 + c2;
    c2 = c1 + 5;
    c2 = 7 + c1;
    }
    //对应 c1 + c2
    inline complex
    operator + (const complex& x,const complex& y){
    return complex (real(x) + real(y) , imag(x) + imag(y));
    }
    
    //对应 c1 + 5
    inline complex
    operator + (const complex& x,double y){
    return complex (real(x) + y , imag(x));
    }
    
    //对应 5 + c1
    inline complex
    operator + (double x,const complex& y){
    return complex (x + real(y) , imag(y));
    }

    这里也看出来 + 操作也分很多种不同情况。
    为什么这里不能传引用呢,可以跟刚才的对比一下,
    因为刚才我们传引用之后进行 += 操作之后,是将结果直接传给了C1,而现在我们没有一个地方存放结果,如果传引用,函数一结束,直接死亡,就等于什么也没做,所以我们需要一个临时complex对象,去存放结果,再将临时对象的结果返回到 c2 , 这样才是正确的,然后销毁临时对象。

    注:typename() 就等于是创建临时变量,像上面的 complex( ... , ... ),也可以是int(7),double(3.65)等等...


    最后是关于返回类型的注意事项
    比如说:

    inline complex&
    complex::operator += (const complex& r){
    return __doapl(this,r);
    }
    改成:
    inline void
    complex::operator += (const complex& r){
    return __doapl(this,r);
    }

    会引起什么问题呢
    如果说是 c1+=c2; 这样依然不会有任何问题,因为c2赋值到c1上(也就是执行__doapl()之后就完成了)
    不用再管接下来返回的是什么类型了,所以改成void是没有问题的。
    但如果是 c3 += c2 += c1;呢,当c1 赋值到 c2 上后,c2必须还要以 complex 类型 加到c3身上,如果返回的是void类型,那么是无法加到c3上面的,所以设计上考虑周全一点,还是会以第一种形式设计重载。

  • 相关阅读:
    变量的解构赋值 (1)对象
    变量的解构赋值 (1)数组
    const 命令
    let 命令
    【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治
    【BZOJ3771】Triple 生成函数+FFT
    【BZOJ4976】宝石镶嵌 DP
    【BZOJ4972】小Q的方格纸 前缀和
    【BZOJ4998】星球联盟 LCT+并查集
    【BZOJ4710】[Jsoi2011]分特产 组合数+容斥
  • 原文地址:https://www.cnblogs.com/xiangqi/p/14273044.html
Copyright © 2020-2023  润新知