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上面的,所以设计上考虑周全一点,还是会以第一种形式设计重载。